﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using System.ComponentModel;
using System.Globalization;
using System.Collections.Specialized;
using System.Xml;
using System.Dynamic;

namespace Anno
{
    /// <summary>
    /// 常用字符串处理
    /// </summary>
    public static class Exts
    {
        //public static string GetAppSetting(string strKey, string def = "")
        //{
        //    try
        //    {
        //        var tem = Furion.App.Configuration[strKey];
        //        if (string.IsNullOrWhiteSpace(tem))
        //            return def;
        //        return tem.Trim();
        //    }
        //    catch { return def; }
        //}
        /// <summary>
        /// 检查 Object 是否为 NULL 或者 0
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsNullOrZero(this object value)
        {
            return value == null || value.NullToStr() == "0";
        }

        ///// <summary>
        ///// 检查是否为 AJAX 请求
        ///// </summary>
        ///// <param name="request"></param>
        ///// <returns></returns>
        //public static bool IsAjaxRequest(this Microsoft.AspNetCore.Http.HttpRequest request)
        //{
        //    if (request == null)
        //        throw new ArgumentNullException(nameof(request));

        //    if (request.Headers != null)
        //        return request.Headers["X-Requested-With"] == "XMLHttpRequest";
        //    return false;
        //}
        /// <summary>
        /// 判断是否为Null或者空
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this object obj)
        {
            if (obj == null || obj == DBNull.Value)
            {
                return true;
            }
            else
            {
                if (obj is string)
                {
                    var objStr = obj.ToString();
                    return string.IsNullOrWhiteSpace(objStr);
                }
                return false;
            }
        }
        /// <summary>
        /// 判断是否不为Null或者空
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        public static bool IsNotNullOrEmpty(this object obj)
        {
            return !IsNullOrEmpty(obj);
        }

        #region GetPropertyValue/SetPropertyValue
        /// <summary>
        /// 获取对象属性值
        /// </summary>
        /// <param name="from"></param>
        /// <param name="_to"></param>
        public static object GetPropertyValue(this Object from, string _propertyName)
        {
            try
            {
                if (from == null || string.IsNullOrEmpty(_propertyName))
                    return null;

                Type ctype = from.GetType();
                System.Reflection.PropertyInfo[] pis = ctype.GetProperties();
                foreach (System.Reflection.PropertyInfo cpi in pis)
                {
                    try
                    {
                        if (_propertyName.Trim().ToLower() == cpi.Name.Trim().ToLower())
                            return cpi.GetValue(from, null);
                    }
                    catch (Exception ex)
                    {
                        Log.Log.Error("GetPropertyValue1," + ex.Message);
                    }
                }
                //---------------------------------------------------------------------
                System.Reflection.FieldInfo[] fis = ctype.GetFields();
                foreach (System.Reflection.FieldInfo cfi in fis)
                {
                    try
                    {
                        if (_propertyName.Trim().ToLower() == cfi.Name.Trim().ToLower())
                            return cfi.GetValue(from);
                    }
                    catch (Exception ex)
                    {
                        Log.Log.Error("GetPropertyValue2," + ex.Message);
                    }
                }
            }
            catch (Exception ex) { Log.Log.Error("GetPropertyValue," + ex.ToString()); }
            return null;
        }

        /// <summary>
        /// 用索引化属性的可选索引值设置指定对象的该属性值  xjh 2016 8 3
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <param name="val"></param>
        public static void SetPropertyValue(this object obj, string propertyName, object val)
        {
            if (obj == null || val == null || val == DBNull.Value || string.IsNullOrEmpty(val.ToString()) || string.IsNullOrEmpty(propertyName))
                return;
            try
            {
                System.Reflection.PropertyInfo property = obj.GetType().GetProperty(propertyName);//得到第i列的所有属性
                if (property != null)
                {
                    if (property.CanWrite)//判断对象是否为空，属性是否为空，属性是否可写！如果都为true
                    {
                        try
                        {
                            //if(!(property.PropertyType.Equals(typeof(string) || property.PropertyType.Equals(typeof(DateTime)) && .val
                            if (val.GetType().Equals(property.PropertyType))
                                property.SetValue(obj, val, null);//o对象，reader[i]对象的新值，索引器空的
                            else
                                property.SetValue(obj, Convert.ChangeType(val, property.PropertyType, null), null);
                        }
                        catch (Exception ex)
                        {
                            Log.Log.Error("SetPropertyValue1," + ex.Message);
                        }
                    }
                }
                else
                {
                    System.Reflection.FieldInfo field = obj.GetType().GetField(propertyName);
                    if (field != null)
                    {
                        try
                        {
                            if (val.GetType().Equals(field.FieldType))
                                field.SetValue(obj, val);
                            else
                                field.SetValue(obj, Convert.ChangeType(val, field.FieldType, null));
                        }
                        catch (Exception ex)
                        {
                            Log.Log.Error("SetPropertyValue2," + ex.Message);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Log.Error("SetPropertyValue," + ex.Message);
            }
        }
        #endregion
        /// <summary>
        /// 转换为字符串,空对象转换为空字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string NullToStr(this object obj)
        {
            if (obj == null || obj == System.DBNull.Value)
                return "";
            else
                return obj.ToString().Trim();
        }

        /// <summary>
        /// 为空返回字符串"null",否则返回其实际值
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string IntToStr(this int? obj)
        {
            if (obj.HasValue)
                return obj.Value.ToString();
            else
                return "null";
        }

        /// <summary>
        /// 为空返回字符串"null",否则返回其实际值
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string DecimalToStr(this decimal? obj)
        {
            if (obj.HasValue)
                return obj.Value.ToString();
            else
                return "null";
        }

        /// <summary>
        /// 转换为字符串,空对象转换为空字符串,并带单引号
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string NullToStrWithExpr(this object obj)
        {
            if (string.IsNullOrEmpty(NullToStr(obj)))
                return Expr("");
            return Expr(obj.ToString().Trim());
        }

        /// <summary>
        /// 为字符串加单引号
        /// </summary>
        /// <param name="Str">要处理的字符串</param>
        /// <returns></returns>
        public static string Expr(this string Str)
        {
            return "'" + Str.Replace("'", "''") + "'";
        }

        /// <summary>
        /// 转换为int,空对象转换为0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static int NullToInt(this object obj)
        {
            if (obj == null || obj == System.DBNull.Value)	//数据库空可以不判断,系统会自动转换为null
                return 0;
            else
                return ToInt32(obj.ToString());
        }

        /// <summary>
        /// 转换为Int64(long),空对象转换为0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static long NullToLong(this object obj)
        {
            if (obj == null || obj == System.DBNull.Value)	//数据库空可以不判断,系统会自动转换为null
                return 0;
            else try
                {
                    return long.Parse(obj.ToString());
                }
                catch { return 0; }
        }

        /// <summary>
        /// 转换为Int16(short),空对象转换为0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static short NullToShort(this object obj)
        {
            if (obj == null || obj == System.DBNull.Value)	//数据库空可以不判断,系统会自动转换为null
                return 0;
            else try
                {
                    return short.Parse(obj.ToString());
                }
                catch { return 0; }
        }

        /// <summary>
        /// 转换为Int16(short),空对象转换为0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static float NullToFloat(this object obj)
        {
            if (obj == null || obj == System.DBNull.Value)	//数据库空可以不判断,系统会自动转换为null
                return 0;
            else try
                {
                    return float.Parse(obj.ToString());
                }
                catch { return 0; }
        }

        /// <summary>
        /// 把一个字符串类型转化为可能的整型
        /// </summary>
        /// <param name="S"></param>
        /// <returns></returns>
        public static int ToInt32(this string S)
        {
            S = S.Trim();
            if (S.Trim() == "") return (0);
            if (S.IndexOf("-") >= 0)
            {   //有负号，但不是开头，则转换为0
                if (S.StartsWith("-") == false) return (0);
                if (S.StartsWith("--")) return (0);
            }
            for (int i = 0; i < S.Length; i++)
            {
                switch (S.Substring(i, 1))
                {
                    case "0":
                    case "1":
                    case "2":
                    case "3":
                    case "4":
                    case "5":
                    case "6":
                    case "7":
                    case "8":
                    case "9":
                        break;
                    case "-":
                        if (S.Length == 1) return (0);
                        break;
                    default:
                        if (i == 0)
                            return (0);
                        else
                            try { return (Convert.ToInt32(S.Substring(0, i))); }
                            catch { return 0; }
                }
            }
            try { return (Convert.ToInt32(S)); }
            catch { return 0; }
        }

        /// <summary>
        /// 判断字符串是否包含非数字字符
        /// </summary>
        /// <returns>返回是否</returns>
        public static bool IsNumber(this string str)
        {
            foreach (char _chr in str)
                if (!Char.IsNumber(_chr))
                    return false;

            return true;
        }

        /// <summary>
        /// 判断字符串是否数字
        /// </summary>
        /// <returns>返回是否</returns>
        public static bool IsNumeric(this object str)
        {
            try
            {
                decimal _d = Convert.ToDecimal(str);
            }
            catch
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 转换为Decimal,空对象转换为0.0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Decimal NullToDecimal(this object obj)
        {
            if (obj == null || obj == System.DBNull.Value)	//数据库空可以不判断,系统会自动转换为null
                return 0.0M;
            else
                return ToDecimal(obj.ToString());
        }
        /// <summary>
        /// 转换为double,空对象转换为0.0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static double NullToDouble(this object obj)
        {
            if (obj == null || obj == System.DBNull.Value)	//数据库空可以不判断,系统会自动转换为null
                return 0.0;
            else
                return ToDouble(obj.ToString());
        }

        /// <summary>
        /// 把一个字符串类型转化为可能的俘点型
        /// </summary>
        /// <param name="S"></param>
        /// <returns></returns>
        public static double ToDouble(this string S)
        {
            bool Flag = false;
            S = S.Trim();
            if (S.Trim() == "") return (0);
            if (S.IndexOf("-") >= 0)
            {   //有负号，但不是开头，则转换为0
                if (S.StartsWith("-") == false) return (0);
                if (S.StartsWith("--")) return (0);
            }
            for (int i = 0; i < S.Length; i++)
            {
                switch (S.Substring(i, 1))
                {
                    case "0":
                    case "1":
                    case "2":
                    case "3":
                    case "4":
                    case "5":
                    case "6":
                    case "7":
                    case "8":
                    case "9":
                        break;
                    case "-":
                        if (S.Length == 1) return (0);      //只有一个点的情况
                        break;
                    case ".":
                        if (S.Length == 1) return (0);      //只有一个点的情况
                        if (Flag == false)
                        {
                            Flag = true;
                        }
                        else
                        {   //如果出现2个点
                            if (i == 0)  //实际不可能 I=0
                                return (0);
                            else         //取这个点之前的内容来进行计算
                                try { return (Convert.ToDouble(S.Substring(0, i))); }
                                catch { return (0); }
                        }
                        break;
                    default:   //出现非法数字
                        if (i == 0)
                            return (0);
                        else
                            try { return (Convert.ToDouble(S.Substring(0, i))); }
                            catch { return (0); }
                }
            }
            try { return (Convert.ToDouble(S)); }
            catch { return 0; }
        }

        /// <summary>
        /// 把一个字符串类型转化为可能的俘点型
        /// </summary>
        /// <param name="S"></param>
        /// <returns></returns>
        public static decimal ToDecimal(this string S)
        {
            bool Flag = false;
            S = S.Trim();
            if (S.Trim() == "") return (0);
            if (S.IndexOf("-") >= 0)
            {   //有负号，但不是开头，则转换为0
                if (S.StartsWith("-") == false) return (0);
                if (S.StartsWith("--")) return (0);
            }
            for (int i = 0; i < S.Length; i++)
            {
                switch (S.Substring(i, 1))
                {
                    case "0":
                    case "1":
                    case "2":
                    case "3":
                    case "4":
                    case "5":
                    case "6":
                    case "7":
                    case "8":
                    case "9":
                        break;
                    case "-":
                        if (S.Length == 1) return (0M);
                        break;
                    case ".":
                        if (S.Length == 1) return (0M);      //只有一个点的情况
                        if (Flag == false)
                        {
                            Flag = true;
                        }
                        else
                        {   //如果出现2个点
                            if (i == 0)  //实际不可能 I=0
                                return (0M);
                            else         //取这个点之前的内容来进行计算
                                try { return (Convert.ToDecimal(S.Substring(0, i))); }
                                catch { return 0m; }
                        }
                        break;
                    default:   //出现非法数字
                        if (i == 0)
                            return (0M);
                        else
                            try { return (Convert.ToDecimal(S.Substring(0, i))); }
                            catch { return 0m; }
                }
            }
            try { return (Convert.ToDecimal(S)); }
            catch { return 0m; }
        }

        /// <summary>
        /// 取字符串srcs左边lenn个字符组成的串
        /// </summary>
        /// <param name="srcs"></param>
        /// <param name="lenn"></param>
        /// <returns></returns>
        public static String LeftStr(String srcs, int lenn)
        {
            return MidStr(srcs, 0, lenn);
        }

        /// <summary>
        /// 取字符串srcs右边lenn个字符组成的串
        /// </summary>
        /// <param name="srcs"></param>
        /// <param name="lenn"></param>
        /// <returns></returns>
        public static String RightStr(this String srcs, int lenn)
        {
            if (srcs.Length >= lenn)
                return MidStr(srcs, srcs.Length - lenn);
            else
                return srcs;
        }

        /// <summary>
        /// 取字符串srcs从startp开始到结尾的字符组成的字符串
        /// </summary>
        /// <param name="srcs"></param>
        /// <param name="startp"></param>
        /// <returns></returns>
        public static String MidStr(this String srcs, int startp)
        {
            if ((startp >= 0) && (srcs.Length >= startp))
                return srcs.Substring(startp);
            else
                return "";
        }

        /// <summary>
        /// 取字符串srcs从startp开始的lenn个长度字符组成的字符串
        /// </summary>
        /// <param name="srcs"></param>
        /// <param name="startp"></param>
        /// <param name="lenn"></param>
        /// <returns></returns>
        public static String MidStr(this String srcs, int startp, int lenn)
        {
            if ((startp >= 0) && (lenn > 0) && (srcs.Length >= startp))
            {
                if (lenn > srcs.Length) lenn = srcs.Length;
                return srcs.Substring(startp, lenn);
            }
            else
                return "";
        }

        /// <summary>
        /// 从字符串strs中取从startp位置开始遇到的第一个subs所在的位置
        /// </summary>
        /// <param name="strs"></param>
        /// <param name="subs"></param>
        /// <param name="startp"></param>
        /// <returns></returns>
        public static int PosStr(this String strs, String subs, int startp)
        {
            if (startp >= strs.Length)
                return -1;
            else
                return strs.IndexOf(subs, startp);
        }

        /// <summary>
        /// 从字符串strs中取遇到的第一个subs所在的位置
        /// </summary>
        /// <param name="strs"></param>
        /// <param name="subs"></param>
        /// <returns></returns>
        public static int PosStr(this String strs, String subs)
        {
            return PosStr(strs, subs, 0);
        }

        /// <summary>
        /// 将字符串srs中标识为ids的值删除，其中dpts为分隔符，equs为等值符
        /// 字符串strs的格式为：&lt;name&gt;&lt;equs&gt;&lt;value&gt;[&lt;dpts&gt;&lt;name&gt;&lt;equs&gt;&lt;value&gt;]
        /// </summary>
        /// <param name="strs"></param>
        /// <param name="dpts"></param>
        /// <param name="equs"></param>
        /// <param name="ids"></param>
        /// <returns></returns>
        public static String DelParmStr(String strs, String dpts, String equs, String ids)
        {
            int pos0, pos1, pos2;
            strs = dpts + strs;
            pos0 = PosStr(strs.ToUpper(), (dpts + ids + equs).ToUpper());
            if (pos0 >= 0)
            {
                pos1 = pos0 + ((string)(dpts + ids + equs)).Length;
                pos2 = PosStr(strs, dpts, pos1);
                if (pos2 >= 0)
                {
                    if (pos0 >= 1)
                        strs = LeftStr(strs, pos0) + MidStr(strs, pos2);
                    else
                        strs = MidStr(strs, pos2);
                }
                else
                {
                    if (pos0 >= 1)
                        strs = LeftStr(strs, pos0);
                    else
                        strs = dpts;
                }
            }
            strs = MidStr(strs, dpts.Length);
            return strs;
        }

        /// <summary>
        /// 将字符串srs中标识为ids的值删除，其中dpts为分隔符，等值符为"="
        /// 字符串strs的格式为：&lt;name&gt;=&lt;value&gt;[&lt;dpts&gt;&lt;name&gt;=&lt;value&gt;]
        /// </summary>
        /// <param name="strs"></param>
        /// <param name="dpts"></param>
        /// <param name="ids"></param>
        /// <returns></returns>
        public static String DelParmStr(String strs, String dpts, String ids)
        {
            return DelParmStr(strs, dpts, "=", ids);
        }

        /// <summary>
        /// 将字符串srs中标识为ids的值删除，其中分隔符为";"，等值符为"="
        /// 字符串strs的格式为：&lt;name&gt;=&lt;value&gt;[;&lt;name&gt;=&lt;value&gt;]
        /// </summary>
        /// <param name="strs"></param>
        /// <param name="ids"></param>
        /// <returns></returns>
        public static String DelParmStr(String strs, String ids)
        {
            return DelParmStr(strs, ";", ids);
        }

        /// <summary>
        /// 将一个整数Ascii码转化为一个字符
        /// </summary>
        /// <param name="ascode"></param>
        /// <returns></returns>
        public static char Chr(int ascode)
        {
            return (char)ascode;
        }

        /// <summary>
        /// 从字符串str中取出第一个字符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static char Chr(string str)
        {
            return Chr(str, 0);
        }

        /// <summary>
        /// 从字符串str中取出第chrpos个字符
        /// </summary>
        /// <param name="str"></param>
        /// <param name="chrpos"></param>
        /// <returns></returns>
        public static char Chr(string str, int chrpos)
        {
            return str.ToCharArray(chrpos, 1)[0];
        }

        /// <summary>
        /// 获取字符chr的Ascii码
        /// </summary>
        /// <param name="chr"></param>
        /// <returns></returns>
        public static int Asc(char chr)
        {
            return Convert.ToInt32(chr);
        }

        /// <summary>
        /// 获取字符串str中第一个字符的Ascii码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int Asc(string str)
        {
            return Asc(str, 0);
        }

        /// <summary>
        /// 获取字符串str中第chrpos个字符的Ascii码
        /// </summary>
        /// <param name="str"></param>
        /// <param name="chrpos"></param>
        /// <returns></returns>
        public static int Asc(string str, int chrpos)
        {
            return Asc(str.ToCharArray(chrpos, 1)[0]);
        }

        /// <summary>
        /// 转换实体内DateTime?类型到字符串
        /// </summary>
        /// <param name="_Date">DateTime? 类型数据</param>
        /// <param name="psFormatStr">样式</param>
        /// <returns>返回字符串</returns>
        public static string NullToDateTimeStr(this DateTime? _Date, string psFormatStr)
        {
            string _lsRT = "";
            if (_Date != null)
                _lsRT = Convert.ToDateTime(_Date).ToString(psFormatStr);

            return _lsRT;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_list"></param>
        /// <returns></returns>
        public static string GetString<T>(List<T> _list)
        {
            var _Str = string.Empty;
            if (_list == null) { return _Str; }
            _list.ForEach(p => _Str += p.ToString() + ";");
            return _Str;
        }

        /// <summary>
        /// object 转换成 DataTime
        /// </summary>
        /// <param name="_Obj"></param>
        /// <returns></returns>
        public static DateTime Obj2DateTime(this object _Obj)
        {
            if (_Obj == null || _Obj is DBNull) { return DateTime.MinValue; }
            if (_Obj is DateTime) { return (DateTime)_Obj; }

            var _Val = DateTime.MinValue;
            bool _IsExp = false;
            try { _Val = Convert.ToDateTime(_Obj.ToString()); }
            catch { _IsExp = true; };
            try
            {
                if (_IsExp)
                {
                    var _Formats = new string[]
                    {
                        "yyyyMMdd",
                        "yyyy/MM/dd",
                        "yyyy-MM-dd",
                        "yyyy.MM.dd",
                        "yyyy MM dd",
                        "yyyy年MM月dd日",
                        "MM/dd/yyyy",
                        "MM-dd-yyyy",
                        "MM.dd.yyyy",
                        "MM dd yyyy",
                        "MM月dd日",
                        "yyyy年MM月",
                        "yyyyMMddHHmm",
                        "yyyyMMddHHmmss",
                        "yyyyMMdd HHmmss",
                        "yyyy/MM/dd HH:mm:ss",
                        "yyyy/MM/dd H:mm:ss",
                        "yyyy.MM.dd HH:mm:ss",
                        "yyyy.MM.dd H:mm:ss",
                        "yyyy-MM-dd HH:mm:ss",
                        "yyyy-MM-dd H:mm:ss",
                        "yyyy-M-d HH:mm:ss",
                        "yyyy-M-d H:mm:ss",
                        "HHmmss",
                        "HH:mm:ss",
                    };
                    _Val = DateTime.ParseExact(_Obj.ToString(), _Formats, null, System.Globalization.DateTimeStyles.None);
                }
            }
            catch { return DateTime.MinValue; }
            return _Val;
        }

        /// <summary>判断当前年份是否是闰年</summary>
        /// <param name="year">年份</param>
        /// <returns></returns>
        public static bool IsLeapYear(this int year)
        {
            int n = year;
            if ((n % 400 == 0) || (n % 4 == 0 && n % 100 != 0))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 时间戳起始日期
        /// </summary>
        private static DateTime TimestampStart = new DateTime(1970, 1, 1, 0, 0, 0, 0);

        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <param name="milliseconds">是否使用毫秒</param>
        /// <returns></returns>
        public static string GetTimeStamp(bool milliseconds = false)
        {
            var ts = DateTime.UtcNow - TimestampStart;
            return Convert.ToInt64(milliseconds ? ts.TotalMilliseconds : ts.TotalSeconds).ToString();
        }

        /// <summary>
        /// 时间戳转日期
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <param name="milliseconds">是否使用毫秒</param>
        /// <returns></returns>
        public static DateTime TimeStamp2DateTime(long timestamp, bool milliseconds = false)
        {
            var value = milliseconds ? 10000 : 10000000;
            return TimestampStart.AddTicks(timestamp * value);
        }
        /// <summary>
        /// 获取周几
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public static string GetWeek(this DateTime datetime)
        {
            var dayOfWeek = datetime.DayOfWeek.GetHashCode();
            string week;
            switch (dayOfWeek)
            {
                case 0:
                    week = "星期日";
                    break;
                case 1:
                    week = "星期一";
                    break;
                case 2:
                    week = "星期二";
                    break;
                case 3:
                    week = "星期三";
                    break;
                case 4:
                    week = "星期四";
                    break;
                case 5:
                    week = "星期五";
                    break;
                default:
                    week = "星期六";
                    break;
            }
            return week;
        }
        #region 获取 本周、本月、本季度、本年 的开始时间或结束时间

        /// <summary>
        /// 获取结束时间
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="date">日期</param>
        /// <returns></returns>
        public static DateTime? GetStart(this DateTime? date, StartAndEndDateType type = StartAndEndDateType.Month)
        {
            var d = date ?? DateTime.Now;

            switch (type)
            {
                case StartAndEndDateType.Week:
                    return d.AddDays(-(int)d.DayOfWeek + 1);
                case StartAndEndDateType.Month:
                    return d.AddDays(-d.Day + 1);
                case StartAndEndDateType.Season:
                    var time = d.AddMonths(0 - ((d.Month - 1) % 3));
                    return time.AddDays(-time.Day + 1);
                case StartAndEndDateType.Year:
                    return d.AddDays(-d.DayOfYear + 1);
                default:
                    return null;
            }
        }

        /// <summary>
        /// 获取结束时间
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="date">日期</param>
        /// <returns></returns>
        public static DateTime? GetEnd(this DateTime? date, StartAndEndDateType type = StartAndEndDateType.Month)
        {
            var d = date ?? DateTime.Now;
            switch (type)
            {
                case StartAndEndDateType.Week:
                    return d.AddDays(7 - (int)d.DayOfWeek);
                case StartAndEndDateType.Month:
                    return d.AddMonths(1).AddDays(-d.AddMonths(1).Day + 1).AddDays(-1);
                case StartAndEndDateType.Season:
                    var time = d.AddMonths((3 - ((d.Month - 1) % 3) - 1));
                    return time.AddMonths(1).AddDays(-time.AddMonths(1).Day + 1).AddDays(-1);
                case StartAndEndDateType.Year:
                    var time2 = d.AddYears(1);
                    return time2.AddDays(-time2.DayOfYear);
                default:
                    return null;
            }
        }

        #endregion

        /// <summary>
        /// 连续按实际长度获取字符串中的数据 从第1位开始计算start
        /// </summary>
        /// <param name="Str"></param>
        /// <param name="Start"></param>
        /// <param name="Length"></param>
        /// <returns></returns>
        public static string MidStrB(this string Str, int Start, int Length)
        {
            int L = LenB(Str);
            if (L < Start) return "";

            string T = "";
            for (int i = 0; i < Str.Length; i++)
            {
                if (LenB(Str.Substring(0, i + 1)) >= Start)
                    T = T + Str.Substring(i, 1);

                if (LenB(T) >= Length)
                    return MyTrim(T);
            }
            return ""; //MidStrB = MyTrim(MidStrB);
        }

        /// <summary>
        /// 字符串长度包括汉字两位
        /// </summary>
        /// <param name="Str"></param>
        /// <returns></returns>
        public static int LenB(this string Str)
        {
            return System.Text.Encoding.Default.GetByteCount(Str);
        }

        /// <summary>
        /// 可以将Chr(0)结束的字符串截取空格
        /// </summary>
        /// <param name="Str"></param>
        /// <returns></returns>
        public static string MyTrim(this string Str)
        {
            string T = "";
            int i;

            int L = Str.Length;
            for (i = 0; i < L; i++)
            {
                T = Str.Substring(i, 1);
                if (T != " " && Convert.ToInt32(Convert.ToChar(T)) != 0)
                {
                    break;
                }
            }
            Str = Str.Substring(i, L - i);

            L = Str.Length;
            for (i = L - 1; i >= 0; i--)
            {
                T = Str.Substring(i, 1);
                if (T != " " && Convert.ToInt32(Convert.ToChar(T)) != 0)
                {
                    break;
                }
            }
            Str = Str.Substring(0, i + 1);

            return Str;
        }

        /// <summary>
        /// 字符串补空格
        /// </summary>
        /// <param name="psStr">字符串</param>
        /// <param name="piCount">总长度</param>
        /// <returns>返回传入字符串</returns>
        public static string SetStrNSP(this string psStr, int piCount)
        {
            while (Encoding.Default.GetByteCount(psStr) <= piCount)
            {
                psStr += " ";
            }
            return psStr;
        }

        /// <summary>
        /// 获取类的某属性名称 (eg:  string s = GetPropName&lt;T>(p => p.prop1);)
        /// </summary>
        /// <typeparam name="T">类名</typeparam>
        /// <param name="expr">lambda表达式</param>
        /// <returns>属性的名称</returns>
        public static string GetPropName<T>(Expression<Func<T, object>> expr)
        {
            try
            {
                switch (expr.Body.NodeType)
                {
                    case ExpressionType.MemberAccess:
                        return ((MemberExpression)expr.Body).Member.Name;
                    case ExpressionType.Convert:
                        return ((MemberExpression)((UnaryExpression)expr.Body).Operand).Member.Name;
                    default:
                        return string.Empty;
                }
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 获取时间类型sql字符串
        /// </summary>
        /// <param name="dt">时间</param>
        /// <param name="IsOracle">是否是oracle数据库</param>
        /// <returns></returns>
        public static string GetSqlTimeStr(this DateTime? dt, bool IsOracle = false)
        {
            if (dt == null) return "NULL";
            if (IsOracle)
                return "TO_DATE('" + ((DateTime)dt).ToString("yyyy-MM-dd HH:mm:ss") + "','YYYY-MM-DD HH24:MI:SS')";
            return "'" + ((DateTime)dt).ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
        }

        /// <summary>
        /// 针对可null值类型做数据库insert时转换成"NULL"
        /// </summary>
        /// <param name="obj">值类型如:int? decimal? double? ...</param>
        /// <returns></returns>
        public static string NullToDBStr(this object obj)
        {
            if (obj == null) { return "NULL"; }
            return obj.ToString();
        }

        /// <summary>
        /// 字符串转换成bool值
        /// </summary>
        /// <param name="_str">字符串</param>
        /// <param name="_bool">bool值的默认值</param>
        /// <returns></returns>
        public static bool GetBool(string _str, bool _bool)
        {
            if (!string.IsNullOrEmpty(_str))
                try { _bool = Convert.ToBoolean(_str); }
                catch { }
            return _bool;
        }

        /// <summary>
        /// 字符串转换成Int值
        /// </summary>
        /// <param name="_str">字符串</param>
        /// <param name="_defaut">int默认值</param>
        /// <param name="_max">最大值</param>
        /// <param name="_min">最小值</param>
        /// <returns></returns>
        public static int GetInt(string _str, int _defaut, int _max = 0, int _min = 0)
        {
            if (string.IsNullOrEmpty(_str)) return _defaut;

            int _temp = 0;
            try { _temp = NullToInt(_str); }
            catch { return _defaut; }

            if ((_temp >= _min && _temp <= _max) || (_max == _min && _max == 0))
                return _temp;

            return _defaut;
        }

        /// <summary>
        /// 字符串转换成List string
        /// </summary>
        /// <param name="_str">字符串</param>
        /// <param name="_chr">截取方式</param>
        /// <returns></returns>
        public static List<string> GetList(string _str, char _chr = ',')
        {
            List<string> _list = new List<string>();
            if (!string.IsNullOrEmpty(_str))
                try { _list = _str.Split(_chr).ToList(); }
                catch { }
            return _list;
        }

        /// <summary>
        /// 字符串转换成double
        /// </summary>
        /// <param name="_str">字符串</param>
        /// <param name="_double">默认值</param>
        /// <returns></returns>
        public static double GetDouble(string _str, double _double)
        {
            if (!string.IsNullOrEmpty(_str))
                try { _double = NullToDouble(_str); }
                catch { }
            return _double;
        }

        /// <summary>
        /// 字符串转换成decimal
        /// </summary>
        /// <param name="_str">字符串</param>
        /// <param name="_decimal">默认值</param>
        /// <returns></returns>
        public static decimal GetDecimal(string _str, decimal _decimal)
        {
            if (!string.IsNullOrEmpty(_str))
                try { _decimal = NullToDecimal(_str); }
                catch { }
            return _decimal;
        }

        /// <summary>
        /// 发票号累加
        /// </summary>
        /// <param name="_invoiceNumber">发票号</param>
        /// <param name="_count">发票张数</param>
        /// <returns></returns>
        public static string InvoiceNumberAdd(string _invoiceNumber, int _count)
        {
            int _index = _invoiceNumber.ToList().FindLastIndex(p => !Char.IsDigit(p));

            string _head = _index >= 0 ? _invoiceNumber.Substring(0, _index + 1) : string.Empty;
            string _number = _index >= 0 ? _invoiceNumber.Substring(_index + 1) : _invoiceNumber;

            long _result = 0;
            if (long.TryParse(_number, out _result))
                _result += _count;

            return _head + _result.ToString().PadLeft(_number.Length, '0');
        }

        #region IsNullOrEmpty_
        ///// <summary>验证字符串是否为 null 或为空</summary>
        ///// <param name="source">要验证的字符串</param>
        ///// <returns>指示字符串是否为 null 或为空</returns>
        //public static bool IsNullOrEmpty_(this string source)
        //{
        //    return string.IsNullOrEmpty(source);
        //}
        /// <summary>
		/// 判断是否不为Null或者空
		/// </summary>
		/// <param name="obj">对象</param>
		/// <returns></returns>
		public static bool IsNotNullOrEmpty_(this object obj)
        {
            return !obj.IsNullOrEmpty_();
        }
        /// <summary>
        /// 判断是否不为Null或者空
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        public static bool IsNotNullOrEmpty_(this string obj)
        {
            return !obj.IsNullOrEmpty_();
        }
        /// <summary>验证字符串是否为 null 或为空</summary>
        /// <param name="source">要验证的字符串</param>
        /// <returns>指示字符串是否为 null 或为空</returns>
        public static bool IsNullOrEmpty_(this string source)
        {
            return string.IsNullOrEmpty(source) || null == source;
        }
        /// <summary>验证对象是否为 null 或数据库字段 null 值</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="value">要验证的对象</param>
        /// <returns>指示对象是否为 null 或数据库字段 null 值</returns>
        public static bool IsNullOrEmpty_<T>(this T value)
        {
            if (value == null || Convert.IsDBNull(value))
            {
                return true;
            }
            else if (value is T[])
            {
                return (value as T[]).IsNullOrEmptyArr_();
            }
            else if (value is IEnumerable)
            {
                return (value as IEnumerable).IsNullOrEmptyArr_();
            }
            else if (value is IEnumerable<T>)
            {
                return (value as IEnumerable<T>).IsNullOrEmptyArr_();
            }
            else
            {
                string objStr = value.ToString();
                return string.IsNullOrEmpty(objStr);
            }
        }
        /// <summary>验证 GUID 是否为 null 或为空</summary>
        /// <param name="guid">要验证的 GUID</param>
        /// <returns>指示 GUID 是否为 null 或为空</returns>
        public static bool IsNullOrEmpty_(this Guid guid)
        {
            return guid == null || guid == Guid.Empty;
        }
        /// <summary>验证数组是否为 null 或为空</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要验证的数组</param>
        /// <returns>指示数组是否为 null 或为空</returns>
        public static bool IsNullOrEmptyArr_<T>(this T[] source)
        {
            return null == source || source.Length == 0;
        }
        /// <summary>验证集合是否为 null 或为空</summary>
        /// <param name="source">要验证的集合</param>
        /// <returns>指示集合是否为 null 或为空</returns>
        public static bool IsNullOrEmptyArr_(this IEnumerable source)
        {
            if (null == source) return true;
            var _source = source as ICollection;
            if (null != _source) return _source.Count == 0;
            foreach (var s in source) return false;
            return false;
        }

        /// <summary>验证集合是否为 null 或为空</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要验证的集合</param>
        /// <returns>指示集合是否为 null 或为空</returns>
        public static bool IsNullOrEmptyArr_<T>(this IEnumerable<T> source)
        {
            if (null == source) return true;

            var _source = source as ICollection<T>;
            if (null != _source) return _source.Count == 0;
            var _source2 = source as ICollection;
            if (null != _source2) return _source2.Count == 0;
            foreach (T _item in source) return false;
            return true;
        }


        /// <summary>验证是否为虚属性</summary>
        /// <param name="property">属性信息</param>
        /// <returns>指示是否为虚属性</returns>
        public static bool IsVirtual(this PropertyInfo property)
        {
            var get = property?.GetGetMethod();
            if (get != null && get.IsVirtual) return true;
            var set = property?.GetSetMethod();
            if (set != null && set.IsVirtual) return true;
            return false;
        }
        /// <summary>验证字符串是否为 null 或为空白字符串</summary>
        /// <param name="source">要验证的字符串</param>
        /// <returns>指示字符串是否为 null 或为空白字符串</returns>
        public static bool IsNullOrWhiteSpace_(this string source)
        {
            if (null == source) return true;
            for (int i = 0, len = source.Length; i < len; i++)
                if (!source[i].IsWhiteSpace_()) return false;
            return true;
        }

        /// <summary>验证对象是否为 null</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要验证的对象</param>
        /// <returns>指示对象是否为 null</returns>
        public static bool IsNull_<T>(this T source)
        {
            return null == source;
        }

        /// <summary>验证字符串是否为空</summary>
        /// <param name="source">要验证的字符串</param>
        /// <returns>指示字符串是否为空</returns>
        public static bool IsEmpty_(this string source)
        {
            return source.Length == 0;
        }

        /// <summary>验证 GUID 是否为空</summary>
        /// <param name="guid">要验证的 GUID</param>
        /// <returns>指示 GUID 是否为空</returns>
        public static bool IsEmpty_(this Guid guid)
        {
            return guid == Guid.Empty;
        }

        /// <summary>验证集合是否为 null 或为空</summary>
        /// <param name="source">要验证的集合</param>
        /// <returns>指示集合是否为 null 或为空</returns>
        public static bool IsNullOrEmpty_(this IEnumerable source)
        {
            if (null == source) return true;
            var _source = source as ICollection;
            if (null != _source) return _source.Count == 0;
            foreach (var s in source) return false;
            return false;
        }

        /// <summary>验证集合是否为 null 或为空</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要验证的集合</param>
        /// <returns>指示集合是否为 null 或为空</returns>
        public static bool IsNullOrEmpty_<T>(this IEnumerable<T> source)
        {
            if (null == source) return true;

            var _source = source as ICollection<T>;
            if (null != _source) return _source.Count == 0;
            var _source2 = source as ICollection;
            if (null != _source2) return _source2.Count == 0;
            foreach (T _item in source) return false;
            return true;
        }

        /// <summary>验证数组是否为 null 或为空</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要验证的数组</param>
        /// <returns>指示数组是否为 null 或为空</returns>
        public static bool IsNullOrEmpty_<T>(this T[] source)
        {
            return null == source || source.Length == 0;
        }

        /// <summary>验证对象是否为数据库字段 null 值</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="value">要验证的对象</param>
        /// <returns>指示对象是否为数据库字段 null 值</returns>
        public static bool IsDBNull_<T>(this T value)
        {
            return Convert.IsDBNull(value);
        }

        /// <summary>验证对象是否为 null 或数据库字段 null 值</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="value">要验证的对象</param>
        /// <returns>指示对象是否为 null 或数据库字段 null 值</returns>
        public static bool IsNullOrDBNull_<T>(this T value)
        {
            return null == value || Convert.IsDBNull(value);
        }
        #endregion

        #region 验证字符
        /// <summary>验证字符是否属于 ASCII 字符(0-127)</summary>
        /// <param name="c">要验证的字符</param>
        /// <returns>指示是否属于 ASCII 字符(0-127)</returns>
        public static bool IsAscii_(this char c)
        {
            return c <= '\x007f';
        }

        /// <summary>验证字符是否属于拉丁字符(0-255)</summary>
        /// <param name="c">要验证的字符</param>
        /// <returns>指示是否属于拉丁字符(0-255)</returns>
        public static bool IsLatin_(this char c)
        {
            return c <= '\x00ff';
        }

        /// <summary>验证字符是否属于空白字符</summary>
        /// <param name="c">要验证的字符</param>
        /// <returns>指示是否属于空白字符</returns>
        public static bool IsWhiteSpace_(this char c)
        {
            if (char.IsWhiteSpace(c)) return true;
            if (c == '﻿') return true;
            return false;
        }

        /// <summary>验证字符是否属于十六进制字符</summary>
        /// <param name="c">要验证的字符</param>
        /// <returns>指示是否属于十六进制字符</returns>
        public static bool IsHex_(this char c)
        {
            //if(char.IsDigit(c)) return true;
            //if(c.Between_('a', 'f', true)) return true;
            //if(c.Between_('A', 'F', true)) return true;
            //return false;
            return (c >= '0' && c <= '9')
                || (c >= 'A' && c <= 'F')
                || (c >= 'a' && c <= 'f');
        }
        #endregion

        #region In_
        /// <summary>验证对象是否存在于集合中</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要验证的对象</param>
        /// <param name="array">用于验证的集合</param>
        /// <returns>指示对象是否存在于集合中</returns>
        public static bool In_<T>(this T obj, IEnumerable<T> array)
        {
            if (null == obj || IsNullOrEmpty_(array)) return false;
            //ICollection<T> _array = array as ICollection<T>;
            //if(null != _array)
            //    return _array.Contains(obj);
            //else
            //{
            //    IEqualityComparer<T> _comparer = EqualityComparer<T>.Default;
            //    foreach(T _item in array)
            //        if(_comparer.Equals(_item, obj)) return true;
            //}
            //return false;
            return array.Contains(obj);
        }

        /// <summary>验证对象是否存在于集合中</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要验证的对象</param>
        /// <param name="array">用于验证的集合</param>
        /// <returns>指示对象是否存在于集合中</returns>
        public static bool In_<T>(this T obj, params T[] array)
        {
            return obj.In_(array as IEnumerable<T>);
        }

        /// <summary>验证字符串是否跟数组中的字符串匹配</summary>
        /// <param name="str">要比较的字符串</param>
        /// <param name="ignoreCase">是否区分大小写</param>
        /// <param name="full">是否完整匹配</param>
        /// <param name="atArray">非完整匹配时，true 为验证数组中的字符串是否包含要匹配的字符串，false 为验证要匹配的字符串是否包含数组里的字符串</param>
        /// <param name="strArray">要比较的字符串数组</param>
        /// <returns>指示字符串是否跟数组中的字符串匹配</returns>
        /// <remarks>
        /// 非完整匹配时，atArray 为 true 时验证数组中的字符串是否包含要匹配的字符串，为 false 时验证要匹配的字符串是否包含数组里的字符串
        /// </remarks>
        public static bool In_(this string str, bool ignoreCase = true, bool full = true, bool atArray = false, params string[] strArray)
        {
            if (string.IsNullOrEmpty(str) || IsNullOrEmpty_(strArray)) return false;

            StringComparison _sc = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
            string _tmp;
            return strArray.Any(s =>
            {
                if (s.IsNullOrEmpty_()) return false;

                _tmp = s.Trim();

                if (full)
                {
                    if (str.Equals(_tmp, _sc)) return true;
                }
                else
                {
                    if (atArray)
                    {
                        if (_tmp.IndexOf(str, _sc) > -1) return true;
                    }
                    else
                    {
                        if (str.IndexOf(_tmp, _sc) > -1) return true;
                    }
                }
                return false;
            });
        }

        /// <summary>验证字符串是否跟数组中的字符串匹配</summary>
        /// <param name="str">要比较的字符串</param>
        /// <param name="list">要比较的字符串列表</param>
        /// <param name="split">列表分隔符</param>
        /// <param name="ignoreCase">是否区分大小写</param>
        /// <returns>指示字符串是否跟数组中的字符串匹配</returns>
        /// <remarks>默认的 list 以半角逗号（,）拆分；默认忽略大小写。</remarks>
        public static bool In_(this string str, string list, string split = ",", bool ignoreCase = true)
        {
            return str.In_(ignoreCase, true, false, list.Split_(split));
        }
        #endregion
        #region 拆分字符串
        /// <summary>拆分字符串</summary>
        /// <param name="str">要拆分的字符串</param>
        /// <param name="split">用于分隔的字符串</param>
        /// <param name="splitOption">拆分选项</param>
        /// <returns>拆分后的字符串数组</returns>
        public static string[] Split_(this string str, string split, StringSplitOptions splitOption = StringSplitOptions.None)
        {
            if (str.IsNull_()) return EmptyArray<string>();
            if (splitOption == StringSplitOptions.RemoveEmptyEntries && str.IsEmpty_()) return EmptyArray<string>();
            if (split.IsNullOrEmpty_() || !str.Contains(split)) return GetArray(str);
            if (split.Length == 1)
                return str.Split(GetArray(split[0]), splitOption);
            return str.Split(GetArray(split), splitOption);
        }

        /// <summary>以给出的正则表达式拆分字符串</summary>
        /// <param name="str">用于拆分的字符串</param>
        /// <param name="pattern">正则表达式。可以使用内联 (?imnsx-imnsx:) 分组构造或 (?imnsx-imnsx) 其他构造设置选项，一个选项或一组选项前面的减号 (-) 用于关闭这些选项。例如，内联构造 (?ix-ms)
        /// <para>* i 指定不区分大小写的匹配</para>
        /// <para>* m 指定多行模式。更改 ^ 和 $ 的含义，以使它们分别与任何行的开头和结尾匹配，而不只是与整个字符串的开头和结尾匹配</para>
        /// <para>* n 指定唯一有效的捕获是显式命名或编号的 (?&lt;name&gt;…) 形式的组。这允许圆括号充当非捕获组，从而避免了由 (?:…) 导致的语法上的笨拙</para>
        /// <para>* s 指定单行模式。更改句点字符 (.) 的含义，以使它与每个字符（而不是除 \n 之外的所有字符）匹配</para>
        /// <para>* x 指定从模式中排除非转义空白并启用数字符号 (#) 后面的注释</para></param>
        /// <param name="ignoreCase">是否忽略大小写</param>
        /// <returns>拆分后的字符串数组</returns>
        public static string[] Split_(this string str, string pattern, bool ignoreCase)
        {
            if (str.IsNullOrEmpty_()) return EmptyArray<string>();
            if (pattern.IsNullOrEmpty_()) return GetArray(str);
            return Regex.Split(str, pattern, ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None);
        }
        // 数组操作

        /// <summary>返回空数组</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <returns>一个长度为 0 的空数组</returns>
        public static T[] EmptyArray<T>()
        {
            return new T[0];
        }

        /// <summary>以传入的参数包装成数组</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="value">要包装的参数</param>
        /// <returns>以传入的参数组成的数组</returns>
        public static T[] GetArray<T>(params T[] value)
        {
            return value;
        }

        /// <summary>将传入的参数合并成数组</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="item">要合并的对象</param>
        /// <param name="value">要合并的集合</param>
        /// <returns>合并成的数组</returns>
        public static IEnumerable<T> Concat_<T>(this T item, params T[] value)
        {
            if (item == null && value.IsNullOrEmpty_())
                return null;
            if (item == null) return value;
            if (value.IsNullOrEmpty_()) return GetArray(item);

            return GetArray(item).Concat(value);
        }

        /// <summary>将传入的参数合并成数组</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要合并的集合</param>
        /// <param name="item">要合并的对象</param>
        /// <returns>合并成的数组</returns>
        public static IEnumerable<T> Concat_<T>(this IEnumerable<T> source, T item)
        {
            if (item == null && source.IsNullOrEmpty_())
                return null;
            if (item == null) return source;
            if (source.IsNullOrEmpty_()) return GetArray(item);

            return source.Concat(GetArray(item));
        }

        /// <summary>以指定的大小创建新数组</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="size">数组大小</param>
        /// <returns>一个指定大小的空数组</returns>
        public static T[] NewArray<T>(int size)
        {
            return new T[size];
        }

        /// <summary>设置数组大小</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要设置的数组</param>
        /// <param name="size">新数组的大小</param>
        /// <returns>一个指定大小的新数组</returns>
        public static T[] SetSize_<T>(this T[] source, int size)
        {
            if (size <= 0) return EmptyArray<T>();
            T[] newArray = NewArray<T>(size);
            if (source.IsNullOrEmpty_()) return newArray;
            int len = source.Length;
            if (size == len) return source;

            Array.Copy(source, 0, newArray, 0, (len > size) ? size : len);
            return newArray;
        }

        /// <summary>设置数组大小</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要设置的数组</param>
        /// <param name="size">新数组的大小</param>
        /// <param name="defval">当新数组大小大于源数组时要添加的默认值</param>
        /// <returns>一个指定大小的新数组</returns>
        public static T[] SetSize_<T>(this T[] source, int size, T defval)
        {
            if (size <= 0) return EmptyArray<T>();
            T[] newArray = NewArray<T>(size);
            int len = source.IsNullOrEmpty_() ? 0 : source.Length;
            if (size == len) return source;

            int copyLen = size;
            if (size > len)
            {
                copyLen = len;
                for (int i = len - 1; i < size; i++)
                    newArray[i] = defval;
            }
            if (len > 0)
                Array.Copy(source, 0, newArray, 0, copyLen);

            return newArray;
        }

        /// <summary>复制集合。复制后的集合元素会受原元素的修改影响</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要复制的集合</param>
        /// <returns>新集合</returns>
        public static List<T> Copy_<T>(this List<T> source)
        {
            return source.GetRange(0, source.Count);
        }

        /// <summary>复制集合。复制后的集合元素会受原元素的修改影响</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要复制的集合</param>
        /// <returns>新集合</returns>
        public static IEnumerable<T> Copy_<T>(this IEnumerable<T> source)
        {
            return source.ToList().Copy_();
        }

        /// <summary>将非 null 对象添加到集合</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">原集合</param>
        /// <param name="item">要添加的对象</param>
        /// <returns>新集合</returns>
        public static List<T> Add_<T>(this List<T> source, T item)
        {
            if (source == null) return null;
            if (item != null)
                source.Add(item);
            return source;
        }

        /// <summary>将非 null 对象添加到集合</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">原集合</param>
        /// <param name="item">要添加的对象</param>
        /// <returns>新集合</returns>
        public static ICollection<T> Add_<T>(this ICollection<T> source, T item)
        {
            if (source == null) return null;
            if (item != null)
                source.Add(item);
            return source;
        }

        /// <summary>串连数组为字符串</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">要串连的数组</param>
        /// <param name="separator">分隔符</param>
        /// <returns>串连后的新字符串</returns>
        public static string Join_<T>(this IEnumerable<T> source, string separator = null)
        {
            if (source.IsNullOrEmpty_()) return string.Empty;

            if (separator == null)
                return string.Concat(source);
            return string.Join(separator, source);
        }

        /// <summary>串连数组为字符串</summary>
        /// <param name="source">要串连的数组</param>
        /// <param name="separator">分隔符</param>
        /// <returns>串连后的新字符串</returns>
        public static string Join_(this string[] source, string separator = null)
        {
            if (source.IsNullOrEmpty_()) return string.Empty;

            if (separator == null)
                return string.Concat(source);
            return string.Join(separator, source);
        }

        /// <summary>对集合中的每个元素执行指定操作</summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="action">要对集合中的每个元素执行的委托</param>
        public static void ForEach_<T>(this IEnumerable<T> source, Action<T> action)
        {
            if (source == null) return;
            foreach (T item in source)
                action(item);
        }

        /// <summary>对集合中的每个元素执行指定操作</summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="action">要对集合中的每个元素执行的委托</param>
        public static void ForEach_<T>(this IEnumerable<T> source, Action<T, int> action)
        {
            if (source == null) return;
            var i = 0;
            foreach (T item in source)
            {
                action(item, i);
                i++;
            }
        }

        /// <summary>检索指定的元素在集合中第一次出现的索引位置，如果没找到则返回 -1</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="value">要检索的元素</param>
        /// <param name="comparer">相等比较器</param>
        /// <returns>元素在集合中第一次出现的索引位置，如果没找到则返回 -1</returns>
        public static int IndexOf_<T>(this IEnumerable<T> source, T value, IEqualityComparer<T> comparer = null)
        {
            var i = -1;
            if (source != null && value != null)
            {
                //comparer = comparer ?? EqualityComparer<T>.Default;
                foreach (T obj in source)
                {
                    i++;
                    if ((comparer == null && value.Equals(obj)) || comparer.Equals(obj, value))
                        break;
                }
            }
            return i;
        }

        /// <summary>获取元素位于集合中的下一个元素</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="item">要检索的元素</param>
        /// <param name="comparer">相等比较器</param>
        /// <returns>下一个元素</returns>
        public static T GetNext_<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer = null)
        {
            if (source.IsNullOrEmpty_() || item == null) return default(T);
            var i = source.IndexOf_(item, comparer);
            if (i == -1) return default(T);
            return source.ElementAtOrDefault(i);
        }

        /// <summary>获取元素位于集合中的上一个元素</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="item">要检索的元素</param>
        /// <param name="comparer">相等比较器</param>
        /// <returns>上一个元素</returns>
        public static T GetPrevious_<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer = null)
        {
            if (source.IsNullOrEmpty_()) return default(T);
            var i = source.IndexOf_(item, comparer);
            if (i < 1) return default(T);
            return source.ElementAtOrDefault(i - 1);
        }

        /// <summary>返回序列中的最大值或默认值</summary>
        /// <param name="source">集合</param>
        /// <returns>序列中的最大值或默认值</returns>
        public static int MaxOrDefault_(this IEnumerable<int> source)
        {
            if (source.IsNullOrEmpty_()) return 0;
            return source.Max();
        }

        /// <summary>返回序列中的最大值或默认值</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <returns>序列中的最大值或默认值</returns>
        public static T MaxOrDefault_<T>(this IEnumerable<T> source)
        {
            if (source.IsNullOrEmpty_()) return default(T);
            return source.Max();
        }

        /// <summary>返回序列中的最大值或默认值</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="selector">应用于每个元素的转换函数</param>
        /// <returns>序列中的最大值或默认值</returns>
        public static int MaxOrDefault_<T>(this IEnumerable<T> source, Func<T, int> selector)
        {
            if (source.IsNullOrEmpty_()) return 0;
            return source
                .Select(selector)
                .MaxOrDefault_();
        }

        /// <summary>返回序列中的最大值或默认值</summary>
        /// <typeparam name="TSource">集合中元素的数据类型</typeparam>
        /// <typeparam name="TResult">返回的数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="selector">应用于每个元素的转换函数</param>
        /// <returns>序列中的最大值或默认值</returns>
        public static TResult MaxOrDefault_<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
        {
            if (source == null) return default(TResult);
            return source
                .Select(selector)
                .MaxOrDefault_();
        }

        /// <summary>返回序列中的最小值或默认值</summary>
        /// <param name="source">集合</param>
        /// <returns>序列中的最小值或默认值</returns>
        public static int MinOrDefault_(this IEnumerable<int> source)
        {
            if (source.IsNullOrEmpty_()) return 0;
            return source.Min();
        }

        /// <summary>返回序列中的最小值或默认值</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <returns>序列中的最小值或默认值</returns>
        public static T MinOrDefault_<T>(this IEnumerable<T> source)
        {
            if (source.IsNullOrEmpty_()) return default(T);
            return source.Min();
        }

        /// <summary>返回序列中的最小值或默认值</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="selector">应用于每个元素的转换函数</param>
        /// <returns>序列中的最小值或默认值</returns>
        public static int MinOrDefault_<T>(this IEnumerable<T> source, Func<T, int> selector)
        {
            if (source.IsNullOrEmpty_()) return 0;
            return source
                .Select(selector)
                .MinOrDefault_();
        }

        /// <summary>返回序列中的最小值或默认值</summary>
        /// <typeparam name="TSource">集合中元素的数据类型</typeparam>
        /// <typeparam name="TResult">返回的数据类型</typeparam>
        /// <param name="source">集合</param>
        /// <param name="selector">应用于每个元素的转换函数</param>
        /// <returns>序列中的最小值或默认值</returns>
        public static TResult MinOrDefault_<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
        {
            if (source == null) return default(TResult);
            return source
                .Select(selector)
                .MinOrDefault_();
        }
        #endregion
        /// <summary>
        /// 获取子类型
        /// </summary>
        /// <param name="oldType"></param>
        /// <returns></returns>
        public static Type GetUnderType(this Type oldType)
        {
            bool isNullable = false;
            return GetUnderType(oldType, ref isNullable);
        }
        /// <summary>
        /// 获取子类型
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="isNullable"></param>
        /// <returns></returns>
        public static Type GetUnderType(this Type oldType, ref bool isNullable)
        {
            Type unType = Nullable.GetUnderlyingType(oldType);
            isNullable = unType != null;
            return unType == null ? oldType : unType;
        }
        /// <summary>
        /// 获取子类型
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="isNullable"></param>
        /// <returns></returns>
        public static Type GetUnderType(this PropertyInfo propertyInfo, ref bool isNullable)
        {
            Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType);
            isNullable = unType != null;
            unType = unType ?? propertyInfo.PropertyType;
            return unType;
        }
        /// <summary>
        /// 获取子类型
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <returns></returns>
        public static Type GetUnderType(this PropertyInfo propertyInfo)
        {
            bool isNullable = false;
            return GetUnderType(propertyInfo, ref isNullable);
        }
        /// <summary>
        /// 支持可以赋值为null的值类型
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <returns></returns>
        public static bool IsNullable(this PropertyInfo propertyInfo)
        {
            Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType);
            return unType != null;
        }
        /// <summary>
        /// 支持可以赋值为null的值类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsNullable(this Type type)
        {
            Type unType = Nullable.GetUnderlyingType(type);
            return unType != null;
        }
        /// <summary>验证是否为可 null 类型</summary>
		/// <typeparam name="T">数据类型</typeparam>
		/// <param name="value">要验证的对象</param>
		/// <returns>指示是否为可 null 类型</returns>
		public static bool IsNullable<T>(this T value)
        {
            return value?.GetType().IsNullable() == true;
        }

        public static bool IsClass(this Type thisValue)
        {
            return thisValue != typeof(string) && thisValue.IsClass;
        }

        /// <summary>验证是否为结构数据</summary>
        /// <param name="type">要验证的类型</param>
        /// <returns>指示是否为结构数据</returns>
        public static bool IsStruct(this Type type)
        {
            return ((type.IsValueType && !type.IsEnum) && (!type.IsPrimitive && !type.IsSerializable));
        }

        /// <summary>验证是否为结构数据</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="value">要验证的对象</param>
        /// <returns>指示是否为结构数据</returns>
        public static bool IsStruct<T>(this T value)
        {
            return typeof(T).IsStruct();
        }

        public static T IsNullReturnNew<T>(T returnObj) where T : new()
        {
            if (returnObj.IsNullOrEmpty())
            {
                returnObj = FastReflection.FastInstance<T>();
            }
            return returnObj;
        }
        /// <summary>
        /// 将 DateTimeOffset 转换成 DateTime
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime ConvertToDateTime(this DateTimeOffset dateTime)
        {
            if (dateTime.Offset.Equals(TimeSpan.Zero))
                return dateTime.UtcDateTime;
            else if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime)))
                return DateTime.SpecifyKind(dateTime.DateTime, DateTimeKind.Local);
            else
                return dateTime.DateTime;
        }

        /// <summary>
        /// 将 DateTime 转换成 DateTimeOffset
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTimeOffset ConvertToDateTimeOffset(this DateTime dateTime)
        {
            return DateTime.SpecifyKind(dateTime, DateTimeKind.Local);
        }
        /// <summary>
        /// 将一个对象转换为指定类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T ChangeType<T>(this object obj)
        {
            return (T)ChangeType(obj, typeof(T));
        }

        /// <summary>
        /// 将一个对象转换为指定类型
        /// </summary>
        /// <param name="obj">待转换的对象</param>
        /// <param name="type">目标类型</param>
        /// <returns>转换后的对象</returns>
        public static object ChangeType(this object obj, Type type)
        {
            if (type == null) return obj;
            if (obj == null) return type.IsValueType ? Activator.CreateInstance(type) : null;

            var underlyingType = Nullable.GetUnderlyingType(type);
            if (type.IsAssignableFrom(obj.GetType())) return obj;
            else if ((underlyingType ?? type).IsEnum)
            {
                if (underlyingType != null && string.IsNullOrEmpty(obj.ToString())) return null;
                else return Enum.Parse(underlyingType ?? type, obj.ToString());
            }
            // 处理DateTime -> DateTimeOffset 类型
            else if (obj.GetType().Equals(typeof(DateTime)) && (underlyingType ?? type).Equals(typeof(DateTimeOffset)))
            {
                return ((DateTime)obj).ConvertToDateTimeOffset();
            }
            // 处理 DateTimeOffset -> DateTime 类型
            else if (obj.GetType().Equals(typeof(DateTimeOffset)) && (underlyingType ?? type).Equals(typeof(DateTime)))
            {
                return ((DateTimeOffset)obj).ConvertToDateTime();
            }
            else if (typeof(IConvertible).IsAssignableFrom(underlyingType ?? type))
            {
                try
                {
                    return Convert.ChangeType(obj, underlyingType ?? type, null);
                }
                catch
                {
                    return underlyingType == null ? Activator.CreateInstance(type) : null;
                }
            }
            else if (type.IsClass && type != typeof(string)
                && (obj is Newtonsoft.Json.Linq.JObject
                || (obj.GetType().IsClass && obj.GetType() != typeof(string))))
            {
                return JsonHelper.DeserializeObjectByJson(
                    JsonHelper.SerializeObjectToJson(obj), type);
            }
            else
            {
                var converter = TypeDescriptor.GetConverter(type);
                if (converter.CanConvertFrom(obj.GetType())) return converter.ConvertFrom(obj);

                var constructor = type.GetConstructor(Type.EmptyTypes);
                if (constructor != null)
                {
                    var o = constructor.Invoke(null);
                    var propertys = type.GetProperties();
                    var oldType = obj.GetType();

                    foreach (var property in propertys)
                    {
                        var p = oldType.GetProperty(property.Name);
                        if (property.CanWrite && p != null && p.CanRead)
                        {
                            property.SetValue(o, ChangeType(p.GetValue(obj, null), property.PropertyType), null);
                        }
                    }
                    return o;
                }
            }
            return obj;
        }

        ///// <summary>
        ///// 通用类型转换 Convert.ChangeType
        ///// </summary>
        ///// <param name="value"></param>
        ///// <param name="type"></param>
        ///// <returns></returns>
        //public static object ChanageType(this object value, Type type)
        //{
        //    if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
        //    if (value == null) return null;
        //    if (type == value.GetType()) return value;
        //    if (type == typeof(string)) return value.NullToStr();
        //    //if (type.IsEnum)
        //    //{
        //    //    if (value is string)
        //    //        return Enum.Parse(type, value as string);
        //    //    else
        //    //        return Enum.ToObject(type, value);
        //    //}
        //    if (!type.IsInterface && type.IsGenericType)
        //    {
        //        Type innerType = type.GetGenericArguments()[0];
        //        object innerValue = ChanageType(value, innerType);
        //        return Activator.CreateInstance(type, new object[] { innerValue });
        //    }
        //    if (value is string && type == typeof(Guid)) return new Guid(value as string);
        //    if (value is string && type == typeof(Version)) return new Version(value as string);
        //    if (value.GetType().IsClass && !value.GetType().Equals(typeof(string))) return ChanageObjectType(value, type);
        //    if (!(value is IConvertible)) return value;
        //    //return Convert.ChangeType(value, type);
        //    return Utilities.FuncTable2Entity.ConvertType(value, type);
        //}
        ///// <summary>
        ///// 通用类型转换 Convert.ChangeType
        ///// </summary>
        ///// <typeparam name="T">返回类型</typeparam>
        ///// <param name="value"></param>
        ///// <returns></returns>
        //public static T ChanageType<T>(this object value)
        //{
        //    if (ChanageType(value, typeof(T)) is T ret) return ret;
        //    return default(T);
        //}
        /// <summary>
        ///  Deserializes the JSON to the specified .NET type.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object ChanageObjectType(this object obj, Type type)
        {
            if (obj?.GetType().IsClass == true && obj?.GetType().Equals(typeof(string)) == false && !type.Equals(typeof(void)))
                return JsonHelper.DeserializeObjectByJson(JsonHelper.SerializeObjectToJson(obj), type);
            else return obj;
        }

        /// <summary>
        /// 判断方法是否是异步
        /// </summary>
        /// <param name="method">方法</param>
        /// <returns></returns>
        public static bool IsAsync(this MethodInfo method)
        {
            return method.ReturnType.IsAsync();
        }

        /// <summary>
        /// 判断类型是否是异步类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsAsync(this Type type)
        {
            return type.ToString().StartsWith(typeof(Task).FullName);
        }
        /// <summary>
        /// 判断指定类型是否实现于该类型
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="implementType"></param>
        /// <returns></returns>
        public static bool IsImplementType(this Type serviceType, Type implementType)
        {
            //泛型
            if (serviceType.IsGenericType)
            {
                if (serviceType.IsInterface)
                {
                    var interfaces = implementType.GetInterfaces();
                    if (interfaces.Any(m => m.IsGenericType && m.GetGenericTypeDefinition() == serviceType))
                    {
                        return true;
                    }
                }
                else
                {
                    if (implementType.BaseType != null && implementType.BaseType.IsGenericType && implementType.BaseType.GetGenericTypeDefinition() == serviceType)
                    {
                        return true;
                    }
                }
            }
            else
            {
                if (serviceType.IsInterface)
                {
                    var interfaces = implementType.GetInterfaces();
                    if (interfaces.Any(m => m == serviceType))
                        return true;
                }
                else
                {
                    if (implementType.BaseType != null && implementType.BaseType == serviceType)
                        return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 判断类型是否实现某个泛型
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="generic">泛型类型</param>
        /// <returns>bool</returns>
        public static bool HasImplementedRawGeneric(this Type type, Type generic)
        {
            // 检查接口类型
            var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
            if (isTheRawGenericType) return true;

            // 检查类型
            while (type != null && type != typeof(object))
            {
                isTheRawGenericType = IsTheRawGenericType(type);
                if (isTheRawGenericType) return true;
                type = type.BaseType;
            }

            return false;

            // 判断逻辑
            bool IsTheRawGenericType(Type type1) => generic == (type1.IsGenericType ? type1.GetGenericTypeDefinition() : type1);
        }
        /// <summary>
        /// 判断是否是匿名类型
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        public static bool IsAnonymous(this object obj)
        {
            var type = obj.GetType();

            return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
                   && type.IsGenericType && type.Name.Contains("AnonymousType")
                   && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
                   && type.Attributes.HasFlag(TypeAttributes.NotPublic);
        }

        /// <summary>
        /// 获取所有祖先类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<Type> GetAncestorTypes(this Type type)
        {
            var ancestorTypes = new List<Type>();
            while (type != null && type != typeof(object))
            {
                if (IsNoObjectBaseType(type))
                {
                    var baseType = type.BaseType;
                    ancestorTypes.Add(baseType);
                    type = baseType;
                }
                else break;
            }

            return ancestorTypes;

            bool IsNoObjectBaseType(Type type1) => type1.BaseType != typeof(object);
        }

        /// <summary>
        /// 获取方法真实返回类型
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        public static Type GetMethodRealReturnType(this MethodInfo method)
        {
            // 判断是否是异步方法
            var isAsyncMethod = method.IsAsync();

            // 获取类型返回值并处理 Task 和 Task<T> 类型返回值
            var returnType = method.ReturnType;
            return isAsyncMethod ? (returnType.GetGenericArguments().FirstOrDefault() ?? typeof(void)) : returnType;
        }
#if !NET40
        /// <summary>
        /// 返回异步类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="realType"></param>
        /// <returns></returns>
        public static object ToTaskResult(this object obj, Type realType)
        {
            return typeof(Task).GetMethod(nameof(Task.FromResult)).MakeGenericMethod(realType).Invoke(null, new object[] { obj });
        }
#endif
        #region 文本转换
        /// <summary>转换成首字母大写（每个单词的首字母大写）</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>返回转换后的字符串</returns>
        public static string ToPascalCase_(this string str)
        {
            if (str.IsNullOrEmpty_()) return string.Empty;
            char[] _cs = str.ToCharArray();
            int _len = _cs.Length;
            if (char.IsLower(_cs[0]))
                _cs[0] = char.ToUpperInvariant(_cs[0]);
            for (int i = 1; i < _len; i++)
            {
                if (!char.IsLetter(_cs[i]))
                {
                    i++;
                    if (char.IsLower(_cs[i]))
                        _cs[i] = char.ToUpperInvariant(_cs[i]);
                }
                else
                {
                    if (char.IsUpper(_cs[i]))
                        _cs[i] = char.ToLowerInvariant(_cs[i]);
                }
            }
            return new string(_cs, 0, _len);
        }

        /// <summary>转换成首字母大写（每个单词的首字母大写）</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="separators">字符串中单词间的分隔符</param>
        /// <returns>返回转换后的字符串</returns>
        public static string ToPascalCase_(this string str, params char[] separators)
        {
            if (str.IsNullOrEmpty_()) return string.Empty;
            if (separators.IsNullOrEmpty_()) return str;
            char[] _cs = str.ToCharArray();
            int _len = _cs.Length;
            if (char.IsLower(_cs[0]))
                _cs[0] = char.ToUpperInvariant(_cs[0]);
            for (int i = 1; i < _len; i++)
            {
                if (_cs[i].In_(separators))
                {
                    i++;
                    if (char.IsLower(_cs[i]))
                        _cs[i] = char.ToUpperInvariant(_cs[i]);
                }
                else
                {
                    if (char.IsUpper(_cs[i]))
                        _cs[i] = char.ToLowerInvariant(_cs[i]);
                }
            }
            return new string(_cs, 0, _len);
        }

        /// <summary>转换成驼峰格式（首个单词的首字母小写，其余单词的首字母大写）</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="separators">要清除的分隔符</param>
        /// <returns>返回转换后的字符串</returns>
        public static string ToCamelCase_(this string str, params char[] separators)
        {
            if (str.IsNullOrEmpty_()) return string.Empty;
            if (separators.IsNullOrEmpty_()) return str;
            char[] _cs = NewArray<char>(str.Length);
            int _index = 0;
            bool _ws = false;
            foreach (char c in str)
            {
                if (c.In_(separators))
                {
                    _ws = true;
                    continue;
                }
                else
                {
                    if (_ws)
                    {
                        _cs[_index] = char.IsLower(c) ? char.ToUpperInvariant(c) : c;
                        _ws = false;
                    }
                    else
                    {
                        _cs[_index] = char.IsUpper(c) ? char.ToLowerInvariant(c) : c;
                    }
                    _index++;
                }
            }
            return new string(_cs, 0, _index);
        }

        /// <summary>将连字符分隔转换成驼峰格式（首个单词的首字母小写，其余单词的首字母大写）</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>返回转换后的字符串</returns>
        public static string ToCamelCase_(this string str)
        {
            return str.ToCamelCase_('-');
        }

        /// <summary>将驼峰格式转换成以指定字符分隔</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="separator">分隔符</param>
        /// <returns>返回转换后的字符串</returns>
        public static string ToSeparate_(this string str, string separator = "-")
        {
            if (str.IsNullOrEmpty_()) return string.Empty;
            char[] _cs = str.ToCharArray();
            int _len = _cs.Length;
            char _c;
            StringBuilderEx _str = new StringBuilderEx((int)Math.Ceiling(_len * 1.5));
            _str += _cs[0];
            for (int i = 1; i < _len; i++)
            {
                _c = _cs[i];
                if (char.IsUpper(_c))
                    _str += separator + char.ToLowerInvariant(_c);
                else
                    _str += _c;
            }
            return _str.ToString();
        }

        /// <summary>将驼峰格式转换成以连字符分隔</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>返回转换后的字符串</returns>
        public static string ToHyphenate_(this string str)
        {
            return str.ToSeparate_("-");
        }

        /// <summary>转换文本格式</summary>
        /// <param name="text">要转换的文本</param>
        /// <param name="type">要转换的类型</param>
        /// <returns>返回转换后的字符串</returns>
        public static string ConvertTextCase_(this string text, TextCaseType type)
        {
            if (text.IsNullOrEmpty_()) return string.Empty;
            switch (type)
            {
                case TextCaseType.LowerCase:
                    return text.ToLowerInvariant();
                case TextCaseType.UpperCase:
                    return text.ToUpperInvariant();
                case TextCaseType.PascalCase:
                    return text.ToPascalCase_();
                case TextCaseType.CamelCase:
                    return text.ToCamelCase_();
                case TextCaseType.Hyphenate:
                    return text.ToHyphenate_();
                default:
                    return text;
            }
        }

        /// <summary>清除多余空白</summary>
        /// <param name="str">要清除的字符串</param>
        /// <returns>清除后的字符串</returns>
        public static string Clean_(this string str)
        {
            if (str.IsNullOrEmpty_()) return string.Empty;

            string _str = str.Trim();
            char[] _cs = NewArray<char>(_str.Length);
            int _index = 0;
            bool _ws = false;
            foreach (char c in _str)
            {
                if (c.IsWhiteSpace_())
                {
                    _ws = true;
                    continue;
                }
                else
                {
                    if (_ws)
                    {
                        _cs[_index] = ' ';
                        _ws = false;
                        _index++;
                    }
                    _cs[_index] = c;
                    _index++;
                }
            }
            return new string(_cs, 0, _index);
        }

        /// <summary>格式化时间量</summary>
        /// <param name="num">毫秒数</param>
        /// <returns>返回格式化后的时间量</returns>
        public static string FormatTime(double num)
        {
            TimeSpan ts = TimeSpan.FromMilliseconds(num);
            return ts.ToString_();
        }

        /// <summary>转换 XML 转义符</summary>
        /// <param name="xml">要转换的 XML 文本</param>
        /// <returns>返回转换后的字符串</returns>
        public static string EscapeXml_(this string xml)
        {
            if (xml.IsNullOrEmpty_()) return string.Empty;
            StringBuilder _sb = new StringBuilder(xml, Math.Ceiling(xml.Length * 1.5).ToInt_());
            if (xml.IndexOf('&') > -1)
                _sb.Replace("&", "&amp;");
            if (xml.IndexOf('\'') > -1)
                _sb.Replace("'", "&apos;");
            if (xml.IndexOf('"') > -1)
                _sb.Replace("\"", "&quot;");
            if (xml.IndexOf('<') > -1)
                _sb.Replace("<", "&lt;");
            if (xml.IndexOf('>') > -1)
                _sb.Replace(">", "&rt;");
            return _sb.ToString();
        }

        /// <summary>以给出的正则表达式替换字符串</summary>
        /// <param name="str">要替换的字符串</param>
        /// <param name="pattern">正则表达式。可以使用内联 (?imnsx-imnsx:) 分组构造或 (?imnsx-imnsx) 其他构造设置选项，一个选项或一组选项前面的减号 (-) 用于关闭这些选项。例如，内联构造 (?ix-ms)
        /// <para>* i 指定不区分大小写的匹配</para>
        /// <para>* m 指定多行模式。更改 ^ 和 $ 的含义，以使它们分别与任何行的开头和结尾匹配，而不只是与整个字符串的开头和结尾匹配</para>
        /// <para>* n 指定唯一有效的捕获是显式命名或编号的 (?&lt;name&gt;…) 形式的组。这允许圆括号充当非捕获组，从而避免了由 (?:…) 导致的语法上的笨拙</para>
        /// <para>* s 指定单行模式。更改句点字符 (.) 的含义，以使它与每个字符（而不是除 \n 之外的所有字符）匹配</para>
        /// <para>* x 指定从模式中排除非转义空白并启用数字符号 (#) 后面的注释</para></param>
        /// <param name="replace">替换字符串</param>
        /// <param name="ignoreCase">是否忽略大小写</param>
        /// <returns>返回替换后的字符串</returns>
        public static string Replace_(this string str, string pattern, string replace, bool ignoreCase = false)
        {
            if (str.IsNullOrEmpty_()) return string.Empty;
            if (pattern.IsNullOrEmpty_()) return str;
            return Regex.Replace(str, pattern, replace, ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None);
        }
        #endregion
        /// <summary>
        /// 反射对象类型,执行对象内部方法
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="methodName">方法名</param>
        /// <param name="paramters">参数</param>
        /// <returns>object</returns>
        public static object InvokeMethod(this Type type, string methodName, params object[] paramters)
        {
            return FastReflection.FastInvoke(type, methodName, paramters);
        }

        /// <summary>
        /// 反射执行对象内部方法
        /// </summary>
        /// <param name="target">对象</param>
        /// <param name="methodName">方法名</param>
        /// <param name="paramters">参数</param>
        /// <returns>object</returns>
        public static object InvokeMethod(this object target, string methodName, params object[] paramters)
        {
            return FastReflection.FastInvoke(target, methodName, paramters);
        }

        /// <summary>
        /// 返回类型指定方法信息
        /// </summary>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <param name="paramters"></param>
        /// <returns></returns>
        public static MethodInfo GetMethod(this Type type, string name, params object[] paramters)
        {
            var reval = FastReflection.GetMethodInfo(type, name, paramters);
            return reval;
        }
        /// <summary>
        /// 返回类型构造函数
        /// </summary>
        /// <param name="type"></param>
        /// <param name="types"></param>
        /// <returns></returns>
        public static ConstructorInfo GetConstructor(this Type type, params object[] types)
        {
            var reval = FastReflection.GetConstructor(type, types);
            return reval;
        }
        // 扩展方式转换操作

        #region ToBool_
        /// <summary>将不为 '0' 的字符转换为 true</summary>
        /// <param name="c">要转换的字符，'0' 为 false，其余为 true</param>
        /// <returns>'0' 为 false，其余为 true</returns>
        public static bool ToBool_(this char c)
        {
            return !(c == '0' || c == '\0');
        }

        private static string[] FalseStrings = new string[] { "false", "no", "not", "null", "0" };
        /// <summary>将不为空值、null 值、"false"字符串的内容转换为 true</summary>
        /// <param name="str">要转换的字符串，空值、null 值、"false" 为 false，其余为 true</param>
        /// <returns>空值、null 值、"false" 为 false，其余为 true</returns>
        public static bool ToBool_(this string str)
        {
            if (string.IsNullOrEmpty(str)) return false;
            if (str.In_(FalseStrings)) return false;
            if (str.IsNumber_()) return str.ToDouble_().ToBool_();
            return true;
        }

        /// <summary>将大于 0 的数字或不为空值、null 值、"false"字符串的内容转换为 true</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>大于 0 的数字或不为空值、null 值、"false"字符串的内容转换为 true</returns>
        public static bool ToBool_<T>(this T obj)
        {
            if (null == obj) return false;
            try { return Convert.ToBoolean(obj); }
            catch { return obj.ToString().ToBool_(); }
        }
        #endregion
        #region 验证测试
        /// <summary>验证是否是纯数字字符串</summary>
        /// <param name="str">要验证的字符串</param>
        /// <returns>指示是否为纯数字字符串</returns>
        public static bool IsDigit_(this string str)
        {
            if (str.IsNullOrEmpty_()) return false;
            foreach (char c in str)
                if (!char.IsDigit(c)) return false;
            return true;
        }

        /// <summary>验证是否是数字字符串</summary>
        /// <param name="str">要验证的字符串</param>
        /// <returns>指示是否为数字字符串</returns>
        public static bool IsNumber_(this string str)
        {
            if (str.IsNullOrEmpty_()) return false;
            double num;
            return double.TryParse(str, NumberStyles.Any, null, out num);
        }

        /// <summary>验证是否是整数字符串</summary>
        /// <param name="str">要验证的字符串</param>
        /// <returns>指示是否为整数字符串</returns>
        public static bool IsInt_(this string str)
        {
            if (str.IsNullOrEmpty_()) return false;
            long num;
            return long.TryParse(str, NumberStyles.Integer, null, out num);
        }

        /// <summary>验证是否是 ASCII(0-127)字符串</summary>
        /// <param name="str">要验证的字符</param>
        /// <returns>指示是否为 ASCII(0-127)字符串</returns>
        public static bool IsAscii_(this string str)
        {
            if (str.IsNullOrEmpty_()) return false;
            return str.All(c => c.IsAscii_());
        }

        /// <summary>验证是否是拉丁(0-255)字符串</summary>
        /// <param name="str">要验证的字符</param>
        /// <returns>指示是否为拉丁(0-255)字符串</returns>
        public static bool IsLatin_(this string str)
        {
            if (str.IsNullOrEmpty_()) return false;
            return str.All(c => c.IsLatin_());
        }

        /// <summary>验证是否是空白字符串</summary>
        /// <param name="str">要验证的字符</param>
        /// <returns>指示是否为空白字符串</returns>
        public static bool IsWhiteSpace_(this string str)
        {
            return str.All(c => c.IsWhiteSpace_());
        }

        /// <summary>验证是否是十六进制字符串</summary>
        /// <param name="str">要验证的字符</param>
        /// <returns>指示是否为十六进制字符串</returns>
        public static bool IsHex_(this string str)
        {
            return str.All(c => c.IsHex_());
        }

        /// <summary>验证是否是 Guid 字符串</summary>
        /// <param name="str">要验证的字符串</param>
        /// <returns>指示是否为 Guid 字符串</returns>
        public static bool IsGuid_(this string str)
        {
            if (str.IsNullOrEmpty_()) return false;
            Guid g;
            return Guid.TryParse(str, out g);
        }

        /// <summary>验证是否是 Base64 字符串</summary>
        /// <param name="str">要验证的字符串</param>
        /// <returns>指示是否为 Base64 字符串</returns>
        public static bool IsBase64String_(this string str)
        {
            if (str.IsNullOrEmpty_()) return false;
            //return Regex.IsMatch(str, @"^[A-Za-z0-9\+\/\=]$");
            foreach (char c in str)
            {
                if (char.IsLetterOrDigit(c)) continue;
                if (c == '+' || c == '/' || c == '=') continue;
                return false;
            }
            return true;
        }

        /// <summary>以给出的正则表达式验证匹配字符串</summary>
        /// <param name="str">要验证的字符串</param>
        /// <param name="pattern">正则表达式。可以使用内联 (?imnsx-imnsx:) 分组构造或 (?imnsx-imnsx) 其他构造设置选项，一个选项或一组选项前面的减号 (-) 用于关闭这些选项。例如，内联构造 (?ix-ms)
        /// <para>* i 指定不区分大小写的匹配</para>
        /// <para>* m 指定多行模式。更改 ^ 和 $ 的含义，以使它们分别与任何行的开头和结尾匹配，而不只是与整个字符串的开头和结尾匹配</para>
        /// <para>* n 指定唯一有效的捕获是显式命名或编号的 (?&lt;name&gt;…) 形式的组。这允许圆括号充当非捕获组，从而避免了由 (?:…) 导致的语法上的笨拙</para>
        /// <para>* s 指定单行模式。更改句点字符 (.) 的含义，以使它与每个字符（而不是除 \n 之外的所有字符）匹配</para>
        /// <para>* x 指定从模式中排除非转义空白并启用数字符号 (#) 后面的注释</para></param>
        /// <param name="ignoreCase">是否忽略大小写</param>
        /// <returns>指示是否为匹配的字符串</returns>
        public static bool IsMatch_(this string str, string pattern, bool ignoreCase = false)
        {
            if (str.IsNullOrEmpty_() || pattern.IsNullOrEmpty_()) return false;
            return Regex.IsMatch(str, pattern, ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None);
        }

        private static Regex REG_EMAIL = new Regex(@"^((\w+[-\.\+]*)*\w+)+@((\w+-*)*\w+\.){1,2}\w{2,4}$", RegexOptions.ExplicitCapture | RegexOptions.Compiled);
        /// <summary>验证 Email 地址格式是否正确</summary>
        /// <param name="email">要验证的 Email 地址</param>
        /// <returns>指示是否为 Email 地址格式</returns>
        public static bool IsEmail(string email)
        {
            if (email.IsNullOrEmpty_()) return false;
            return REG_EMAIL.IsMatch(email);
        }

        private static Regex REG_URL = new Regex(@"^(http|https|ftp)\:\/\/[a-z0-9\-\.]+\.[a-z]{2,3}(?::[a-z0-9]*)?\/?\S*$", RegexOptions.ExplicitCapture | RegexOptions.Compiled);
        /// <summary>验证 URL 格式是否正确</summary>
        /// <param name="url">要验证的 URL</param>
        /// <returns>指示是否为 URL 格式</returns>
        public static bool IsUrl(string url)
        {
            if (url.IsNullOrEmpty_()) return false;
            return REG_URL.IsMatch(url);
        }

        /// <summary>验证是否是图像格式文件名</summary>
        /// <param name="fileName">要验证的文件名</param>
        /// <returns>指示是否为图像格式文件名</returns>
        public static bool IsImageFileName(string fileName)
        {
            if (fileName.IsNullOrEmpty_()) return false;
            string[] _exts = new string[5] { ".jpg", ".jpeg", ".png", ".bmp", ".gif" };
            return CheckFileNameByExtension(fileName, _exts);
        }

        /// <summary>验证是否是以某些指定扩展名为结尾的文件名</summary>
        /// <param name="fileName">要验证的文件名</param>
        /// <param name="exts">用于验证的扩展名列表</param>
        /// <returns>指示是否为以某些指定扩展名结尾的文件名</returns>
        public static bool CheckFileNameByExtension(string fileName, string[] exts)
        {
            if (fileName.IsNullOrEmpty_()) return false;
            if (!fileName.Contains(".")) return false;

            string _filename = fileName.ToLowerInvariant();
            foreach (string _ext in exts)
                if (_filename.EndsWith(_ext)) return true;

            return false;
        }
        #endregion
        #region ToChar_
        /// <summary>转换为相应的字符</summary>
        /// <param name="b">要转换的布尔值，true 为 1，false 为 0</param>
        /// <returns>true 为 1，false 为 0</returns>
        public static char ToChar_(this bool b)
        {
            return b ? '1' : '0';
        }

        /// <summary>转换为相应的字符</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>字符串的第一个字符或默认值</returns>
        public static char ToChar_(this string str, char defval = '0')
        {
            return str.IsNullOrEmpty_() ? defval : str[0];
        }

        /// <summary>转换为相应的字符</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的字符或默认值</returns>
        public static char ToChar_<T>(this T obj, char defval = '0')
        {
            if (null == obj) return defval;
            try { return Convert.ToChar(obj); }
            catch { return defval; }
        }

        /// <summary>转换为相应的字符，转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的字符或 null</returns>
        public static char? ToCharOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_())
                return null;
            return str[0];
        }

        /// <summary>转换为相应的字符，转换不成功时返回 null</summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的字符或 null</returns>
        public static char? ToCharOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToChar(obj); }
            catch { return null; }
        }
        #endregion

        #region ToByte_
        /// <summary>转换为相应的整数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static byte ToByte_(this string str, byte defval = 0)
        {
            if (str.IsNullOrEmpty_()) return defval;
            byte _retval;
            if (!byte.TryParse(str, NumberStyles.Any, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换为相应的整数</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static byte ToByte_<T>(this T obj, byte defval = 0)
        {
            if (null == obj) return defval;
            try { return Convert.ToByte(obj); }
            catch { return obj.ToString().ToByte_(defval); }
        }

        /// <summary>转换为相应的整数，转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的整数或 null</returns>
        public static byte? ToByteOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_()) return null;
            byte _retval;
            if (!byte.TryParse(str, NumberStyles.Any, null, out _retval))
                return null;
            return _retval;
        }

        /// <summary>转换为相应的整数，转换不成功时返回 null</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的整数或 null</returns>
        public static byte? ToByteOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToByte(obj); }
            catch { return obj.ToString().ToByteOrNull_(); }
        }
        #endregion

        #region ToInt_
        /// <summary>转换为相应的整数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static int ToInt_(this string str, int defval = 0)
        {
            if (str.IsNullOrEmpty_()) return defval;
            int _retval;
            if (!int.TryParse(str, NumberStyles.Any, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换为相应的整数</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static int ToInt_<T>(this T obj, int defval = 0)
        {
            if (null == obj) return defval;
            try { return Convert.ToInt32(obj); }
            catch { return obj.ToString().ToInt_(defval); }
        }

        /// <summary>转换为相应的整数，转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的整数，转换不成功时返回 null</returns>
        public static int? ToIntOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_()) return null;
            int _retval;
            if (!int.TryParse(str, NumberStyles.Any, null, out _retval))
                return null;
            return _retval;
        }

        /// <summary>转换为相应的整数或 null</summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">要转换的字符串</param>
        /// <returns>相应的整数或 null</returns>
        public static int? ToIntOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToInt32(obj); }
            catch { return obj.ToString().ToIntOrNull_(); }
        }
        #endregion

        #region ToShort_
        /// <summary>转换为相应的整数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static short ToShort_(this string str, short defval = 0)
        {
            if (str.IsNullOrEmpty_()) return defval;
            short _retval;
            if (!short.TryParse(str, NumberStyles.Any, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换为相应的整数</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static short ToShort_<T>(this T obj, short defval = 0)
        {
            if (null == obj) return defval;
            try { return Convert.ToInt16(obj); }
            catch { return obj.ToString().ToShort_(defval); }
        }

        /// <summary>转换为相应的整数，转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的整数或 null</returns>
        public static short? ToShortOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_()) return null;
            short _retval;
            if (!short.TryParse(str, NumberStyles.Any, null, out _retval))
                return null;
            return _retval;
        }

        /// <summary>转换为相应的整数，转换不成功时返回 null</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的整数或 null</returns>
        public static short? ToShortOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToInt16(obj); }
            catch { return obj.ToString().ToShortOrNull_(); }
        }
        #endregion

        #region ToLong_
        /// <summary>转换为相应的整数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static long ToLong_(this string str, long defval = 0L)
        {
            if (str.IsNullOrEmpty_()) return defval;
            long _retval;
            if (!long.TryParse(str, NumberStyles.Any, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换为相应的整数</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static long ToLong_<T>(this T obj, long defval = 0L)
        {
            if (null == obj) return defval;
            try { return Convert.ToInt64(obj); }
            catch { return obj.ToString().ToLong_(defval); }
        }

        /// <summary>转换为相应的整数，转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的整数或 null</returns>
        public static long? ToLongOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_()) return null;
            long _retval;
            if (!long.TryParse(str, NumberStyles.Any, null, out _retval))
                return null;
            return _retval;
        }

        /// <summary>转换为相应的整数，转换不成功时返回 null</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的整数或 null</returns>
        public static long? ToLongOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToInt64(obj); }
            catch { return obj.ToString().ToLongOrNull_(); }
        }
        #endregion

        #region ToFloat_
        /// <summary>转换为相应的单精度浮点数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的单精度浮点数或默认值</returns>
        public static float ToFloat_(this string str, float defval = 0F)
        {
            if (str.IsNullOrEmpty_()) return defval;
            float _retval;
            if (!float.TryParse(str, NumberStyles.Any, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换为相应的单精度浮点数</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的单精度浮点数或默认值</returns>
        public static float ToFloat_<T>(this T obj, float defval = 0F)
        {
            if (null == obj) return defval;
            try { return Convert.ToSingle(obj); }
            catch { return obj.ToString().ToFloat_(defval); }
        }

        /// <summary>转换为相应的单精度浮点数，转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的单精度浮点数或 null</returns>
        public static float? ToFloatOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_()) return null;
            float _retval;
            if (!float.TryParse(str, NumberStyles.Any, null, out _retval))
                return null;
            return _retval;
        }

        /// <summary>转换为相应的单精度浮点数，转换不成功时返回 null</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的单精度浮点数或 null</returns>
        public static float? ToFloatOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToSingle(obj); }
            catch { return obj.ToString().ToFloatOrNull_(); }
        }
        #endregion

        #region ToDouble_
        /// <summary>转换为相应的双精度浮点数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的双精度浮点数或默认值</returns>
        public static double ToDouble_(this string str, double defval = 0D)
        {
            if (str.IsNullOrEmpty_()) return defval;
            double _retval;
            if (!double.TryParse(str, NumberStyles.Any, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换为相应的双精度浮点数</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的双精度浮点数或默认值</returns>
        public static double ToDouble_<T>(this T obj, double defval = 0D)
        {
            if (null == obj) return defval;
            try { return Convert.ToDouble(obj); }
            catch { return obj.ToString().ToDouble_(defval); }
        }

        /// <summary>转换为相应的双精度浮点数，转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的双精度浮点数或 null</returns>
        public static double? ToDoubleOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_()) return null;
            double _retval;
            if (!double.TryParse(str, NumberStyles.Any, null, out _retval))
                return null;
            return _retval;
        }

        /// <summary>转换为相应的双精度浮点数，转换不成功时返回 null</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的双精度浮点数或 null</returns>
        public static double? ToDoubleOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToDouble(obj); }
            catch { return obj.ToString().ToDoubleOrNull_(); }
        }
        #endregion

        #region ToDecimal_
        /// <summary>转换高精度的十进制数（一般用于货币）</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的十进制数或默认值</returns>
        public static decimal ToDecimal_(this string str, decimal defval = 0M)
        {
            if (str.IsNullOrEmpty_()) return defval;
            decimal _retval;
            if (!decimal.TryParse(str, NumberStyles.Any, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换高精度的十进制数（一般用于货币）</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的十进制数或默认值</returns>
        public static decimal ToDecimal_<T>(this T obj, decimal defval = 0M)
        {
            if (null == obj) return defval;
            try { return Convert.ToDecimal(obj); }
            catch { return obj.ToString().ToDecimal_(defval); }
        }

        /// <summary>转换高精度的十进制数（一般用于货币），转换不成功时返回 null</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的十进制数或 null</returns>
        public static decimal? ToDecimalOrNull_(this string str)
        {
            if (str.IsNullOrEmpty_()) return null;
            decimal _retval;
            if (!decimal.TryParse(str, NumberStyles.Any, null, out _retval))
                return null;
            return _retval;
        }

        /// <summary>转换高精度的十进制数（一般用于货币），转换不成功时返回 null</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的十进制数或 null</returns>
        public static decimal? ToDecimalOrNull_<T>(this T obj)
        {
            if (null == obj) return null;
            try { return Convert.ToDecimal(obj); }
            catch { return obj.ToString().ToDecimalOrNull_(); }
        }
        #endregion

        #region ToEnum_
        /// <summary>转换为相应的枚举值</summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的枚举值或默认值</returns>
        public static T ToEnum_<T>(this string str, T defval = default(T)) where T : struct
        {
            if (str.IsNullOrEmpty_()) return defval;
            Type _type = typeof(T);
            if (!_type.IsEnum) return defval;
            T _retval;
            if (Enum.TryParse(str, true, out _retval))
                if (Enum.IsDefined(_type, _retval))
                    return _retval;
            return defval;
        }

        /// <summary>转换为相应的枚举值</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="type">枚举类型</param>
        /// <returns>相应的枚举值或默认值</returns>
        public static object ToEnum_(this string str, Type type)
        {
            return Enum.Parse(type, str, true);
        }

        /// <summary>转换为相应的枚举值</summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="num">要转换的数字</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的枚举值或默认值</returns>
        public static T ToEnum_<T>(this object num, T defval = default(T)) where T : struct
        {
            Type _type = typeof(T);
            if (!_type.IsEnum) return defval;
            try
            {
                T _retval = (T)Enum.ToObject(_type, num);
                if (Enum.IsDefined(_type, _retval))
                    return _retval;
                return defval;
            }
            catch { return num.ToString().ToEnum_(defval); }
        }

        /// <summary>转换为相应的枚举值</summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的枚举值或 null</returns>
        public static T? ToEnumOrNull_<T>(this string str) where T : struct
        {
            if (str.IsNullOrEmpty_()) return null;
            Type _type = typeof(T);
            if (!_type.IsEnum) return null;
            T _retval;
            if (Enum.TryParse(str, true, out _retval))
                if (Enum.IsDefined(_type, _retval))
                    return _retval;
            return null;
        }

        /// <summary>转换为相应的枚举值</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="type">枚举类型</param>
        /// <returns>相应的枚举值或默认值</returns>
        public static object ToEnumOrNull_(this string str, Type type)
        {
            try { return Enum.Parse(type, str, true); }
            catch { return null; }
        }

        /// <summary>转换为相应的枚举值</summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="num">要转换的数字</param>
        /// <returns>相应的枚举值或 null</returns>
        public static T? ToEnumOrNull_<T>(this object num) where T : struct
        {
            Type _type = typeof(T);
            if (!_type.IsEnum) return null;
            try
            {
                T _retval = (T)Enum.ToObject(_type, num);
                if (Enum.IsDefined(_type, _retval))
                    return _retval;
                return null;
            }
            catch { return num.ToString().ToEnumOrNull_<T>(); }
        }
        #endregion

        #region ToString_
        /// <summary>转换为相应的枚举值名称</summary>
        /// <param name="e">要转换的枚举值</param>
        /// <returns>枚举值名称</returns>
        public static string ToString_(this Enum e)
        {
            return null == e ? string.Empty : Enum.GetName(e.GetType(), e);
        }

        /// <summary>转换为不含分隔符的 GUID 字符串</summary>
        /// <param name="g">要转换的 GUID</param>
        /// <returns>不含分隔符的 GUID 字符串</returns>
        public static string ToString_(this Guid g)
        {
            if (g == null) g = Guid.Empty;
            return g.ToString("N");
        }

        /// <summary>将 true 转换为 "1"，false 转换为 "0"</summary>
        /// <param name="b">要转换的布尔值，true 为 "1"，false 为 "0"</param>
        /// <returns>true 为 "1"，false 为 "0"</returns>
        public static string ToString_(this bool b)
        {
            return b ? "1" : "0";
        }

        /// <summary>将 true 转换为 "1"，false 转换为 "0"</summary>
        /// <param name="b">要转换的布尔值，true 为 "1"，false 为 "0"，为 null 时返回空字符串</param>
        /// <returns>true 为 "1"，false 为 "0"，为 null 时返回空字符串</returns>
        public static string ToString_(this bool? b)
        {
            return null == b ? string.Empty : b.Value.ToString_();
        }

        /// <summary>转换为 yyyy-MM-dd HH:mm:ss 格式的字符串</summary>
        /// <param name="time">要转换的日期</param>
        /// <returns>yyyy-MM-dd HH:mm:ss 格式的字符串</returns>
        public static string ToString_(this DateTime time)
        {
            return time.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>转换为 yyyy-MM-dd HH:mm:ss 格式的字符串</summary>
        /// <param name="time">要转换的日期，为 null 时返回空字符串</param>
        /// <returns>yyyy-MM-dd HH:mm:ss 格式或空字符串</returns>
        public static string ToString_(this DateTime? time)
        {
            return null == time ? string.Empty : time.Value.ToString_();
        }

        /// <summary>转换成对应的字符串格式（x 天 xx 小时 xx 分 xx 秒 xxx 毫秒）</summary>
        /// <param name="ts">时间间隔</param>
        /// <returns>“x 天 xx 小时 xx 分 xx 秒 xxx 毫秒”格式的字符串</returns>
        public static string ToString_(this TimeSpan ts)
        {
            StringBuilderEx str = new StringBuilderEx(30);
            bool is0 = true;
            int temp;
            temp = ts.Days;
            if (temp != 0)
            {
                str.Append(temp).Append("天");
                is0 = false;
            }
            temp = ts.Hours;
            if (temp != 0 || !is0)
            {
                str.Append(temp).Append("小时");
            }
            temp = ts.Minutes;
            if (temp != 0 || !is0)
            {
                str.Append(temp).Append("分");
            }
            temp = ts.Seconds;
            if (temp != 0 || !is0)
            {
                str.Append(temp).Append("秒");
            }
            temp = ts.Milliseconds;
            if (temp != 0 || is0)
            {
                str.Append(temp).Append("毫秒");
            }

            return str.TrimEnd().ToString();
        }

        /// <summary>转换成对应的字符串格式（x 天 xx 小时 xx 分 xx 秒 xxx 毫秒）</summary>
        /// <param name="ts">时间间隔，为 null 时返回空字符串</param>
        /// <returns>“x 天 xx 小时 xx 分 xx 秒 xxx 毫秒”格式或空字符串</returns>
        public static string ToString_(this TimeSpan? ts)
        {
            return null == ts ? string.Empty : ts.Value.ToString_();
        }
        #endregion

        #region ToDate_
        /// <summary>转换为相应的日期</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认日期</param>
        /// <returns>相应的日期或默认值</returns>
        public static DateTime ToDate_(this string str, DateTime defval)
        {
            if (str.IsNullOrEmpty_()) return defval;
            DateTime _retval;
            if (!DateTime.TryParse(str, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>转换为相应的日期</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的日期</returns>
        public static DateTime ToDate_(this string str)
        {
            return ToDate_(str, BaseDateTime);
        }

        /// <summary>以指定格式转换为相应的日期</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认日期</param>
        /// <param name="format">日期格式（如：yyyy年MM月dd日 HH时mm分ss秒），如果格式中任一部分跟要转换的字符串不一致，都将导致转换失败而返回默认日期</param>
        /// <returns>相应的日期或默认值</returns>
        public static DateTime ToDate_(this string str, DateTime defval, string format)
        {
            if (str.IsNullOrEmpty_()) return defval;
            if (format.IsNullOrEmpty_()) return str.ToDate_(defval);
            DateTime _retval;
            if (!DateTime.TryParseExact(str, format, null, DateTimeStyles.None, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>以指定格式转换为相应的日期</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="format">日期格式（如：yyyy年MM月dd日 HH时mm分ss秒），如果格式中任一部分跟要转换的字符串不一致，都将导致转换失败而返回默认日期</param>
        /// <returns>相应的日期</returns>
        public static DateTime ToDate_(this string str, string format)
        {
            return ToDate_(str, BaseDateTime, format);
        }

        /// <summary>将以100纳（毫微）秒表示的日期转换为相应的日期</summary>
        /// <param name="num">要转换的数字</param>
        /// <param name="defval">转换不成功时的默认日期</param>
        /// <param name="kind">指示此数字是指定了本地时间、协调世界时 (UTC)，还是两者皆未指定。</param>
        /// <returns>相应的日期或默认值</returns>
        public static DateTime ToDate_(this long num, DateTime defval, DateTimeKind kind = DateTimeKind.Local)
        {
            try { return new DateTime(num, kind); }
            catch { return defval; }
        }

        /// <summary>将以100纳（毫微）秒表示的日期转换为相应的日期</summary>
        /// <param name="num">要转换的数字</param>
        /// <param name="kind">指示此数字是指定了本地时间、协调世界时 (UTC)，还是两者皆未指定。</param>
        /// <returns>相应的日期或默认值</returns>
        public static DateTime ToDate_(this long num, DateTimeKind kind = DateTimeKind.Local)
        {
            return ToDate_(num, BaseDateTime, kind);
        }

        /// <summary>转换为相应的日期</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="defval">转换不成功时的默认日期</param>
        /// <param name="format">如果 obj 为字符串时的日期格式（如：yyyy年MM月dd日 HH时mm分ss秒），如果格式中任一部分跟要转换的字符串不一致，都将导致转换失败而返回默认日期</param>
        /// <returns>相应的日期或默认值</returns>
        public static DateTime ToDate_<T>(this T obj, DateTime defval, string format = null)
        {
            if (null == obj) return defval;
            if (obj is DateTime) return Convert.ToDateTime(obj);
            return obj.ToString().ToDate_(defval, format);
        }

        /// <summary>转换为相应的日期</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <param name="format">如果 obj 为字符串时的日期格式（如：yyyy年MM月dd日 HH时mm分ss秒），如果格式中任一部分跟要转换的字符串不一致，都将导致转换失败而返回默认日期</param>
        /// <returns>相应的日期</returns>
        public static DateTime ToDate_<T>(this T obj, string format = null)
        {
            return obj.ToDate_(BaseDateTime, format);
        }
        #endregion

        #region ToGuid_
        /// <summary>转换为相应的 GUID</summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>相应的 GUID</returns>
        public static Guid ToGuid_(this string str)
        {
            Guid g = Guid.Empty;
            if (!str.IsNullOrEmpty_())
                Guid.TryParse(str, out g);
            return g;
        }

        /// <summary>转换为相应的 GUID</summary>
        /// <param name="guid">要转换的 GUID</param>
        /// <returns>相应的 GUID</returns>
        public static Guid ToGuid_(this Guid guid)
        {
            return guid;
        }

        /// <summary>转换为相应的 GUID</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="obj">要转换的对象</param>
        /// <returns>相应的 GUID</returns>
        public static Guid ToGuid_<T>(this T obj)
        {
            if (null == obj) return Guid.Empty;
            return obj.ToString().ToGuid_();
        }
        #endregion

        #region ToIEnumerable
        /// <summary>将 Enum 转换为 Dictionary&lt;int, string&gt; 集合</summary>
        /// <typeparam name="T">Enum 类型</typeparam>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns>Dictionary&lt;int, string&gt; 集合</returns>
        public static Dictionary<int, string> ToDict_<T>(System.Resources.ResourceManager res = null, System.Globalization.CultureInfo info = null) where T : struct
        {
            return ToDict_(typeof(T), res, info);
        }

        /// <summary>将 Enum 类型转换为 Dictionary&lt;int, string&gt; 集合</summary>
        /// <param name="type">Enum 类型</param>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns>Dictionary&lt;int, string&gt; 集合</returns>
        public static Dictionary<int, string> ToDict_(Type type, System.Resources.ResourceManager res = null, System.Globalization.CultureInfo info = null)
        {
            if (!type.IsEnum) return null;

            var vals = Enum.GetValues(type);
            if (vals.IsNullOrEmpty_()) return null;
            var dict = new Dictionary<int, string>(vals.Length);
            int key;
            string val, name;
            foreach (var item in vals)
            {
                key = Convert.ChangeType(item, Enum.GetUnderlyingType(type)).ToInt_();
                name = item.ToString();
                if (res != null)
                {
                    val = GetLocalization_(type.Name + "_" + name, res, info);
                    if (val.IsNullOrEmpty_())
                        val = name;
                }
                else
                    val = name;
                dict.Add(key, val);
            }
            return dict;
        }

        /// <summary>将 Enum 转换为 <see cref="NameValueCollection" /> 集合</summary>
        /// <typeparam name="T">Enum 类型</typeparam>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns><see cref="NameValueCollection" /> 集合</returns>
        public static NameValueCollection ToNVC_<T>(System.Resources.ResourceManager res = null, System.Globalization.CultureInfo info = null) where T : struct
        {
            return ToNVC_(typeof(T), res, info);
        }

        /// <summary>将 Enum 类型转换为 <see cref="NameValueCollection" /> 集合</summary>
        /// <param name="type">Enum 类型</param>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns><see cref="NameValueCollection" /> 集合</returns>
        public static NameValueCollection ToNVC_(Type type, System.Resources.ResourceManager res = null, System.Globalization.CultureInfo info = null)
        {
            if (!type.IsEnum) return null;

            var vals = Enum.GetValues(type);
            if (vals.IsNullOrEmpty_()) return null;
            var nvc = new NameValueCollection(vals.Length);
            string key, val, name;
            foreach (var item in vals)
            {
                key = Convert.ChangeType(item, Enum.GetUnderlyingType(type)).ToString();
                name = item.ToString();
                if (res != null)
                {
                    val = GetLocalization_(type.Name + "_" + name, res, info);
                    if (val.IsNullOrEmpty_())
                        val = name;
                }
                else
                    val = name;
                nvc.Add(key, val);
            }
            return nvc;
        }

        /// <summary>将 Enum 转换为 IEnumerable&lt;KeyValuePair&lt;int, string&gt;&gt; 集合</summary>
        /// <typeparam name="T">Enum 类型</typeparam>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns>IEnumerable&lt;KeyValuePair&lt;int, string&gt;&gt; 集合</returns>
        public static IEnumerable<KeyValuePair<int, string>> ToKVL_<T>(System.Resources.ResourceManager res = null, System.Globalization.CultureInfo info = null) where T : struct
        {
            return ToKVL_(typeof(T), res, info);
        }

        /// <summary>将 Enum 类型转换为 IEnumerable&lt;KeyValuePair&lt;int, string&gt;&gt; 集合</summary>
        /// <param name="type">Enum 类型</param>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns>IEnumerable&lt;KeyValuePair&lt;int, string&gt;&gt; 集合</returns>
        public static IEnumerable<KeyValuePair<int, string>> ToKVL_(Type type, System.Resources.ResourceManager res = null, System.Globalization.CultureInfo info = null)
        {
            if (!type.IsEnum) return null;

            var vals = Enum.GetValues(type);
            if (vals.IsNullOrEmpty_()) return null;
            var kvls = new List<KeyValuePair<int, string>>(vals.Length);
            int key;
            string val, name;
            foreach (var item in vals)
            {
                key = Convert.ChangeType(item, Enum.GetUnderlyingType(type)).ToInt_();
                name = item.ToString();
                if (res != null)
                {
                    val = GetLocalization_(type.Name + "_" + name, res, info);
                    if (val.IsNullOrEmpty_())
                        val = name;
                }
                else
                    val = name;
                kvls.Add(new KeyValuePair<int, string>(key, val));
            }
            return kvls;
        }
        #endregion
        #region GetLocalization
        // 其它操作
        /// <summary>基本日期，1900-01-01，主要针对 SQL 数据库的最小日期范围</summary>
        /// <value>针对 SQL 数据库的最小日期</value>
        public static readonly DateTime BaseDateTime = new DateTime(1900, 1, 1);

        /// <summary>获取本地化资源</summary>
        /// <param name="e">要获取的枚举值</param>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns>本地化资源</returns>
        public static string GetLocalization_(this Enum e, System.Resources.ResourceManager res, System.Globalization.CultureInfo info = null)
        {
            var type = e.GetType();
            var name = type.Name + "_" + Enum.GetName(type, e);
            return GetLocalization_(name, res, info);
        }

        /// <summary>获取本地化资源</summary>
        /// <param name="name">要获取的资源名称</param>
        /// <param name="res">所在的本地化资源</param>
        /// <param name="info">区域性信息</param>
        /// <returns>本地化资源</returns>
        public static string GetLocalization_(string name, System.Resources.ResourceManager res, System.Globalization.CultureInfo info = null)
        {
            if (name.IsNullOrEmpty_()) return string.Empty;
            return res.GetString(name, info);
        }
        #endregion
        #region ToStrArray_
        /// <summary>转换成字符串列表</summary>
        /// <param name="list">要转换的列表</param>
        /// <param name="ignoreEmpty">是否忽略掉空格</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <returns>字符串列表</returns>
        public static string[] ToStrArray_(this string[] list, bool ignoreEmpty = false, bool distinct = false)
        {
            if (list.IsNull_()) return EmptyArray<string>();
            if (!ignoreEmpty && !distinct) return list;
            return list.ToStrArray_<IEnumerable<string>>(ignoreEmpty, distinct);
        }

        /// <summary>转换成字符串列表</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="list">要转换的列表</param>
        /// <param name="ignoreEmpty">是否忽略掉空格</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <returns>字符串列表</returns>
        public static string[] ToStrArray_<T>(this IEnumerable<string> list, bool ignoreEmpty = false, bool distinct = false)
        {
            if (list.IsNull_()) return EmptyArray<string>();

            IEnumerable<string> array;
            if (distinct)
                array = __ToStrArrayDistinct(list, ignoreEmpty);
            else if (ignoreEmpty)
                array = __ToStrArray(list, ignoreEmpty);
            else
                array = list;
            return array.ToArray();
        }

        /// <summary>转换成字符串列表</summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="list">要转换的列表</param>
        /// <param name="ignoreEmpty">是否忽略掉空格</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <returns>字符串列表</returns>
        public static string[] ToStrArray_<T>(this IEnumerable<T> list, bool ignoreEmpty = false, bool distinct = false)
        {
            if (list.IsNull_()) return EmptyArray<string>();

            IEnumerable<string> array;
            if (distinct)
                array = __ToStrArrayDistinct(list, ignoreEmpty);
            else
                array = __ToStrArray(list, ignoreEmpty);
            return array.ToArray();
        }

        private static IEnumerable<string> __ToStrArray(IEnumerable<string> list, bool ignoreEmpty)
        {
            foreach (string str in list)
            {
                if (ignoreEmpty && str.Trim().IsNullOrEmpty_()) continue;
                yield return str;
            }
        }
        private static IEnumerable<string> __ToStrArrayDistinct(IEnumerable<string> list, bool ignoreEmpty)
        {
            HashSet<string> hs = new HashSet<string>();
            foreach (string str in list)
            {
                if ((ignoreEmpty && str.Trim().IsNullOrEmpty_()) || hs.Contains(str)) continue;
                hs.Add(str);
                yield return str;
            }
        }
        private static IEnumerable<string> __ToStrArray<T>(IEnumerable<T> list, bool ignoreEmpty)
        {
            string str;
            foreach (T item in list)
            {
                if (item == null) continue;
                str = item.ToString();
                if (ignoreEmpty && str.Trim().IsNullOrEmpty_()) continue;
                yield return str;
            }
        }
        private static IEnumerable<string> __ToStrArrayDistinct<T>(IEnumerable<T> list, bool ignoreEmpty)
        {
            string str;
            HashSet<string> hs = new HashSet<string>();
            foreach (T item in list)
            {
                if (item == null) continue;
                str = item.ToString();
                if ((ignoreEmpty && str.Trim().IsNullOrEmpty_()) || hs.Contains(str)) continue;
                hs.Add(str);
                yield return str;
            }
        }
        #endregion

        #region StrToGuidArray
        /// <summary>将包含 Guid 字符串列表转换成 Guid 列表</summary>
        /// <param name="strList">要转换的字符串列表</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <returns>Guid 列表</returns>
        public static Guid[] ToGuidArray_(this IEnumerable<string> strList, bool distinct = false)
        {
            if (strList.IsNullOrEmpty_()) return EmptyArray<Guid>();
            IEnumerable<Guid> array = distinct ? __ToGuidArrayDistinct(strList) : __ToGuidArray(strList);
            return array.ToArray();
        }

        private static IEnumerable<Guid> __ToGuidArray(IEnumerable<string> strList)
        {
            Guid guid;
            foreach (string str in strList)
            {
                if (str.IsNullOrEmpty_()) continue;
                guid = str.ToGuid_();
                if (guid == Guid.Empty) continue;
                yield return guid;
            }
        }
        private static IEnumerable<Guid> __ToGuidArrayDistinct(IEnumerable<string> strList)
        {
            Guid guid;
            HashSet<Guid> list = new HashSet<Guid>();
            foreach (string str in strList)
            {
                if (str.IsNullOrEmpty_()) continue;
                guid = str.ToGuid_();
                if (guid == Guid.Empty || list.Contains(guid)) continue;
                list.Add(guid);
                yield return guid;
            }
        }
        #endregion

        #region StrToIntArray
        /// <summary>将包含数字字符串列表转换成数字列表</summary>
        /// <param name="strList">要转换的字符串列表</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <returns>数字列表</returns>
        public static int[] ToIntArray_(this IEnumerable<string> strList, bool distinct = false)
        {
            if (strList.IsNullOrEmpty_()) return EmptyArray<int>();
            IEnumerable<int> array = distinct ? __ToIntArrayDistinct(strList) : __ToIntArray(strList);
            return array.ToArray();
        }

        private static IEnumerable<int> __ToIntArray(IEnumerable<string> strList)
        {
            int num;
            foreach (string str in strList)
            {
                if (str.IsNullOrEmpty_() || !int.TryParse(str.Trim(), out num)) continue;
                yield return num;
            }
        }
        private static IEnumerable<int> __ToIntArrayDistinct(IEnumerable<string> strList)
        {
            int num;
            HashSet<int> list = new HashSet<int>();
            foreach (string str in strList)
            {
                if (str.IsNullOrEmpty_() || !int.TryParse(str, out num) || list.Contains(num)) continue;
                list.Add(num);
                yield return num;
            }
        }
        #endregion

        #region ToArray
        /// <summary>将列表转换成另外一种数据类型列表</summary>
        /// <typeparam name="TFrom">源数据类型</typeparam>
        /// <typeparam name="TTo">目标数据类型</typeparam>
        /// <param name="list">要转换的列表</param>
        /// <param name="func">自定义转换函数</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <param name="ec">过滤重复项要用的相等比较器</param>
        /// <returns>转换后的列表</returns>
        public static TTo[] ToArray_<TFrom, TTo>(this IEnumerable<TFrom> list, Func<TFrom, TTo> func, bool distinct = false, IEqualityComparer<TTo> ec = null)
        {
            return list.To_(func, distinct, ec).ToArray();
        }
        /// <summary>将列表转换成另外一种数据类型列表</summary>
        /// <typeparam name="TFrom">源数据类型</typeparam>
        /// <typeparam name="TTo">目标数据类型</typeparam>
        /// <param name="list">要转换的列表</param>
        /// <param name="func">自定义转换函数</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <param name="ec">过滤重复项要用的相等比较器</param>
        /// <returns>转换后的列表</returns>
        public static IEnumerable<TTo> To_<TFrom, TTo>(this IEnumerable<TFrom> list, Func<TFrom, TTo> func, bool distinct = false, IEqualityComparer<TTo> ec = null)
        {
            if (list.IsNullOrEmpty_()) return EmptyArray<TTo>();
            return distinct ? __ToArrayDistinct(list, func, ec) : __ToArray(list, func);
        }
        private static IEnumerable<TTo> __ToArray<TFrom, TTo>(IEnumerable<TFrom> list, Func<TFrom, TTo> func)
        {
            foreach (var item in list)
            {
                yield return func(item);
            }
        }
        private static IEnumerable<TTo> __ToArrayDistinct<TFrom, TTo>(IEnumerable<TFrom> list, Func<TFrom, TTo> func, IEqualityComparer<TTo> ec)
        {
            HashSet<TTo> hs = new HashSet<TTo>(ec);
            foreach (var item in list)
            {
                TTo obj = func(item);
                if (hs.Contains(obj)) continue;
                hs.Add(obj);
                yield return obj;
            }
        }

        /// <summary>将列表转换成另外一种数据类型列表</summary>
        /// <typeparam name="TTo">目标数据类型</typeparam>
        /// <param name="list">要转换的列表</param>
        /// <param name="func">自定义转换函数</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <param name="ec">过滤重复项要用的相等比较器</param>
        /// <returns>转换后的列表</returns>
        public static TTo[] ToArray_<TTo>(this IEnumerable list, Func<object, TTo> func, bool distinct = false, IEqualityComparer<TTo> ec = null)
        {
            return list.To_(func, distinct, ec).ToArray();
        }
        /// <summary>将列表转换成另外一种数据类型列表</summary>
        /// <typeparam name="TTo">目标数据类型</typeparam>
        /// <param name="list">要转换的列表</param>
        /// <param name="func">自定义转换函数</param>
        /// <param name="distinct">是否过滤重复项</param>
        /// <param name="ec">过滤重复项要用的相等比较器</param>
        /// <returns>转换后的列表</returns>
        public static IEnumerable<TTo> To_<TTo>(this IEnumerable list, Func<object, TTo> func, bool distinct = false, IEqualityComparer<TTo> ec = null)
        {
            if (list.IsNullOrEmpty_()) return EmptyArray<TTo>();
            return distinct ? __ToArrayDistinct(list, func, ec) : __ToArray(list, func);
        }
        private static IEnumerable<TTo> __ToArray<TTo>(IEnumerable list, Func<object, TTo> func)
        {
            foreach (var item in list)
            {
                yield return func(item);
            }
        }
        private static IEnumerable<TTo> __ToArrayDistinct<TTo>(IEnumerable list, Func<object, TTo> func, IEqualityComparer<TTo> ec)
        {
            HashSet<TTo> hs = new HashSet<TTo>(ec);
            foreach (var item in list)
            {
                TTo obj = func(item);
                if (hs.Contains(obj)) continue;
                hs.Add(obj);
                yield return obj;
            }
        }
        #endregion

        #region HexTo
        /// <summary>将十六进制字符串转换为相应的整数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static byte HexToByte(string str, byte defval = 0)
        {
            if (str.IsNullOrEmpty_()) return defval;
            byte _retval;
            if (!byte.TryParse(str, NumberStyles.HexNumber, null, out _retval))
                return defval;
            return _retval;
        }

        /// <summary>将十六进制字符串转换为相应的整数</summary>
        /// <param name="str">要转换的字符串</param>
        /// <param name="defval">转换不成功时的默认值</param>
        /// <returns>相应的整数或默认值</returns>
        public static int HexToInt(string str, int defval = 0)
        {
            if (str.IsNullOrEmpty_()) return defval;
            int _retval;
            if (!int.TryParse(str, NumberStyles.HexNumber, null, out _retval))
                return defval;
            return _retval;
        }
        #endregion

        #region ToHex_
        /// <summary>转换成十六进制代码</summary>
        /// <param name="data">要转换的数据</param>
        /// <returns>十六进制代码</returns>
        public static string ToHex_(this byte[] data)
        {
            if (data.IsNullOrEmpty_()) return string.Empty;
            StringBuilderEx str = new StringBuilderEx(data.Length * 2);
            foreach (byte b in data)
                str += b.ToString("X2");
            return str.ToString();
        }

        /// <summary>转换成十六进制代码</summary>
        /// <param name="data">要转换的数据</param>
        /// <param name="separator">各字节间的分隔符</param>
        /// <returns>十六进制代码</returns>
        public static string ToHex_(this byte[] data, string separator)
        {
            if (data.IsNullOrEmpty_()) return string.Empty;
            if (separator.IsNullOrEmpty_()) return data.ToHex_();

            int i = 0, l = data.Length;
            StringBuilderEx str = new StringBuilderEx(l * 3);
            foreach (byte b in data)
            {
                str += b.ToString("X2");
                i++;
                if (i < l) str += separator;
            }
            return str.ToString();
        }
        #endregion

        #region 克隆
        /// <summary>克隆对象</summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">要克隆的对象</param>
        /// <returns>新对象</returns>
        public static T Clone_<T>(this T obj)
        {
            if (obj == null) return default(T);

            var type = obj.GetType();
            if (type.IsValueType)
                return obj;

            var id = obj as IDictionary;
            if (id != null)
                return (T)CloneDict(id);

            var il = obj as IList;
            if (il != null)
                return (T)CloneList(il);

            var ic = obj as ICloneable;
            if (ic != null)
                return (T)ic.Clone();

            var newObj = FastReflection.FastInstance<T>();
            var ls = FastReflection.FastGetAccessors(type);
            foreach (var a in ls.Values)
            {
                if (!a.CanRade || !a.CanWrite)
                    continue;

                a.SetValue(newObj, Clone_(a.GetValue(obj)));
            }
            return newObj;
        }

        private static IDictionary CloneDict(IDictionary list)
        {
            if (list == null) return null;

            IDictionary ls = list.GetType().FastInstance(list.Count) as IDictionary;
            if (ls == null) return null;

            foreach (DictionaryEntry item in list)
                ls.Add(Clone_(item.Key), Clone_(item.Value));
            return ls;
        }

        private static IList CloneList(IList list)
        {
            if (list == null) return null;

            IList ls = list.GetType().FastInstance(list.Count) as IList;
            if (ls == null) return null;

            foreach (var item in list)
                ls.Add(Clone_(item));
            return ls;
        }
        #endregion

        static Random Random = new Random();
        /// <summary>
        /// 获取集合随机下标
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ts"></param>
        /// <returns></returns>
        public static int GetRandomIndex<T>(this IEnumerable<T> ts)
        {
            if (ts.IsNullOrEmpty_()) return 0;
            int maxValue = ts.Count();
            var num = Random.Next(0, maxValue);
            while (num < 0 || num >= maxValue)
            {
                num = Random.Next(0, maxValue);
            }
            return num;
        }
        /// <summary>
        /// 随机获取数组中的一个
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static T RandomGet<T>(this T[] arr)
        {
            if (arr == null || !arr.Any())
                return default(T);

            var r = new Random();

            return arr[r.Next(arr.Length)];
        }

        public static Dictionary<string, string> GetQueryStringDic(this string queryString)
        {
            var rets = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            if (queryString.IsNullOrEmpty_())
                return rets;
            if (queryString.Contains("?"))
                queryString = queryString.Substring(queryString.LastIndexOf("?") + 1);
            var queryStrings = queryString.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var q in queryStrings)
            {
                var qs = q.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                if (qs.Length > 1)
                {
                    rets[qs[0].Trim()] = qs[1].Trim();
                }
            }
            return rets;
        }
        public static string GetQueryString(this Dictionary<string, string> dic)
        {
            var queryString = "";
            if (dic.IsNullOrEmpty_())
                return queryString;
            foreach (var q in dic)
            {
                queryString += "&" + q.Key + "=" + q.Value;
            }
            queryString = queryString.Trim('&');
            return queryString;
        }
        public static string StrToMD5(string str)
        {
            byte[] data = System.Text.UTF8Encoding.Default.GetBytes(str);
            var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] OutBytes = md5.ComputeHash(data);

            string OutString = "";
            for (int i = 0; i < OutBytes.Length; i++)
            {
                OutString += OutBytes[i].ToString("x2");
            }
            // return OutString.ToUpper();
            return OutString.ToLower();
        }

        #region GetFieldPathValue
        /// <summary>
        /// 取对象属性值（如：id 、userInfo.id）
        /// </summary>
        /// <param name="input"></param>
        /// <param name="filedPath"></param>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static object GetFieldPathValue(this object input, string filedPath, string typeName = null)
        {
            if (filedPath.IsNullOrEmpty() || input.IsNullOrEmpty())
                return null;
            //if (typeName.IsNullOrEmpty()) typeName = "string";

            var filedPaths = filedPath.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            object val = null;
            object newVal = input;
            for (var i = 0; i < filedPaths.Length; i++)
            {
                var filedName = filedPaths[i];
                if (filedName.IsNullOrEmpty()) continue;
                if (filedName.Contains("[") && filedName.Contains("]"))//取数组下标值
                {
                    var filedbame = filedName.Substring(0, filedName.IndexOf("["));
                    newVal = GetFieldValue(newVal, filedbame);
                    if (newVal != null)
                    {
                        var index = GetMatchValue(filedName).ChangeType<int>();
                        if (index >= 0 && newVal is System.Collections.IEnumerable array)
                        {
                            newVal = array.CastToList_<object>()[i];
                        }
                    }
                }
                else//取属性值
                {
                    newVal = GetFieldValue(newVal, filedName);
                    if (newVal is string && newVal.NullToStr().IsJson())
                    {
                        newVal = JsonHelper.DeserializeObjectByJson(newVal.NullToStr());
                    }
                    else if (newVal is Newtonsoft.Json.Linq.JValue _jValue && _jValue.Value is string && _jValue.Value.NullToStr().IsJson())
                    {
                        newVal = JsonHelper.DeserializeObjectByJson(_jValue.Value.NullToStr());
                    }
                }

                if (i == filedPaths.Length - 1)
                {
                    val = newVal;
                }
            }
            if (val != null && typeName.IsNotNullOrEmpty())
            {
                var typeoff = GetTypeByName(typeName);
                if (typeoff != null)
                    return val.ChangeType(typeoff);
            }
            return val;
        }
        /// <summary>
        /// 取对象属性值
        /// </summary>
        /// <param name="input"></param>
        /// <param name="filedName"></param>
        /// <returns></returns>
        public static object GetFieldValue(this object input, string filedName)
        {
            if (filedName.IsNullOrEmpty() || input.IsNullOrEmpty())
                return null;
            filedName = filedName.Trim();
            if (input is Newtonsoft.Json.Linq.JObject _jObject)//JSON
            {
                foreach (var item in _jObject)
                {
                    if (item.Key.Trim().ToLower() != filedName.ToLower()) continue;
                    return item.Value;
                }
            }
            else if (input is Newtonsoft.Json.Linq.JArray _ajObject)
            {
                return input;
            }
            else if (input is System.Dynamic.ExpandoObject _eObject)//ExpandoObject
            {
                foreach (var item in _eObject)
                {
                    if (item.Key.Trim().ToLower() != filedName.ToLower()) continue;
                    return item.Value;
                }
            }
            else if (input is System.Collections.Generic.Dictionary<string, object> _dicObject)//Dictionary
            {
                foreach (var item in _dicObject)
                {
                    if (item.Key.Trim().ToLower() != filedName.ToLower()) continue;
                    return item.Value;
                }
            }
            else if (input is System.Collections.Generic.Dictionary<string, string> _dicstr)//Dictionary
            {
                foreach (var item in _dicstr)
                {
                    if (item.Key.Trim().ToLower() != filedName.ToLower()) continue;
                    return item.Value;
                }
            }
            else if (input is System.Collections.IDictionary _idicObject)//IDictionary
            {
                foreach (var item in _idicObject.Keys)
                {
                    if (item.NullToStr().ToLower() != filedName.ToLower()) continue;
                    return _idicObject[item];
                }
            }
            else if (input is string)//string
            {
                return input;
            }
            else//实体
            {
                var property = input.GetType().GetProperties().ToList().Find(item => item.Name.Trim().ToLower() == filedName.ToLower());
                if (property != null)
                {
                    return property.GetValue(input);
                }
                var field = input.GetType().GetFields().ToList().Find(item => item.Name.Trim().ToLower() == filedName.ToLower());
                if (field != null)
                {
                    return field.GetValue(input);
                }
            }
            return null;
        }
        /// <summary>
        /// IEnumerable转换为List'T'
        /// </summary>
        /// <typeparam name="T">参数</typeparam>
        /// <param name="source">数据源</param>
        /// <returns></returns>
        public static List<T> CastToList_<T>(this IEnumerable source)
        {
            return new List<T>(source.Cast<T>());
        }
        #region GetMatchValue
        /// <summary>
        /// 取中括号[]值
        /// </summary>
        /// <param name="template"></param>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static string GetMatchValue(string template, string left = "[", string right = "]")
        {
            var rgx = new System.Text.RegularExpressions.Regex(@"(?i)(?<=\" + left + @")(.*)(?=\" + right + ")");//中括号[]
            var rt = rgx.Match(template).Value;//中括号[]
            return rt;
        }
        #endregion

        #region GetTypeByName
        public static Type GetTypeByName(this string typeName)
        {
            var type = GetTypeByString(typeName);
            if (type != null)
            {
                return type;
            }
            //------------------------------------------------------------------------
            Assembly[] assemblyArray = AppDomain.CurrentDomain.GetAssemblies();
            int assemblyArrayLength = assemblyArray.Length;
            for (int i = 0; i < assemblyArrayLength; ++i)
            {
                type = assemblyArray[i].GetType(typeName);
                if (type != null)
                {
                    return type;
                }
            }
            //------------------------------------------------------------------------
            //for (int i = 0; (i < assemblyArrayLength); ++i)
            //{
            //    Type[] typeArray = assemblyArray[i].GetTypes();
            //    int typeArrayLength = typeArray.Length;
            //    for (int j = 0; j < typeArrayLength; j++)
            //    {
            //        try
            //        {
            //            var tye = typeArray[j];
            //            if (tye != null && tye.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase))
            //            {
            //                return tye;
            //            }
            //        }
            //        catch { }
            //    }
            //}
            return type;
        }
        private static Type GetTypeByString(string type)
        {
            switch (type.ToLower())
            {
                case "bool":
                    return Type.GetType("System.Boolean", false, true);
                case "byte":
                    return Type.GetType("System.Byte", false, true);
                case "sbyte":
                    return Type.GetType("System.SByte", false, true);
                case "char":
                    return Type.GetType("System.Char", false, true);
                case "decimal":
                    return Type.GetType("System.Decimal", false, true);
                case "double":
                    return Type.GetType("System.Double", false, true);
                case "single":
                case "float":
                    return Type.GetType("System.Single", false, true);
                case "int32":
                case "int":
                    return Type.GetType("System.Int32", false, true);
                case "uint32":
                case "uint":
                    return Type.GetType("System.UInt32", false, true);
                case "int64":
                case "long":
                    return Type.GetType("System.Int64", false, true);
                case "uint64":
                case "ulong":
                    return Type.GetType("System.UInt64", false, true);
                case "object":
                    return Type.GetType("System.Object", false, true);
                case "int16":
                case "short":
                    return Type.GetType("System.Int16", false, true);
                case "uint16":
                case "ushort":
                    return Type.GetType("System.UInt16", false, true);
                case "string":
                    return Type.GetType("System.String", false, true);
                case "date":
                case "datetime":
                    return Type.GetType("System.DateTime", false, true);
                case "guid":
                    return Type.GetType("System.Guid", false, true);
                default:
                    return Type.GetType(type, false, true);
            }
        }
        #endregion
        #endregion
        #region GetXmlNodeAttributeValue
        /// <summary>
        /// 选择xmlNode节点的匹配xmlAttributeName的属性XmlAttribute.
        /// </summary>
        /// <param name="xmlNode">X节点</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <returns>返回xmlAttributeName</returns>
        public static string GetXmlNodeAttributeValue(this XmlNode xmlNode, string xmlAttributeName, string defValue = "")
        {
            try
            {
                if (xmlNode != null && xmlNode.Attributes.Count > 0)
                {
                    var Attr = xmlNode.Attributes[xmlAttributeName];
                    if (Attr != null)
                    {
                        var val = Attr.Value;
                        if (!val.IsNullOrEmpty()) return val;
                    }
                }
            }
            catch
            {
            }
            return defValue;
        }

        /// <summary>
        /// 获取列值
        /// </summary>
        /// <param name="dr">DataRow</param>
        /// <param name="colName">列名称</param>
        /// <returns>列值</returns>
        public static string GetXmlNodeAttributeValue(this DataRow dr, string colName, string defValue = "")
        {
            try
            {
                return dr.GetColumnValue(colName, defValue).NullToStr();
            }
            catch
            {
            }
            return defValue;
        }
        public static string GetDynamicAttributeValue(dynamic expando, string proName, string defValue = "")
        {
            try
            {
                if (expando == null || proName.IsNullOrEmpty()) return defValue;
                IDictionary<string, object> dy = expando;
                if (dy == null) return "";
                proName = proName.Trim().ToLower();
                foreach (var dic in dy)
                {
                    if (dic.Key.Trim().ToLower() == proName)
                    {
                        return dic.Value.NullToStr();
                    }
                }
            }
            catch
            {
            }
            return defValue;
        }
        /// <summary>
        /// 选择Newtonsoft.Json.Linq.JToken节点的匹配proName的属性.
        /// </summary>
        /// <param name="jsonNode">json节点</param>
        /// <param name="proName">要匹配proName的属性名称</param>
        /// <returns>返回proName值</returns>
        public static string GetXmlNodeAttributeValue(this Newtonsoft.Json.Linq.JToken jsonNode, string proName, string defValue = "")
        {
            try
            {
                if (jsonNode != null)
                {
                    var val = jsonNode.Value<string>(proName);
                    if (!string.IsNullOrWhiteSpace(val))
                    {
                        return val;
                    }
                }
            }
            catch
            {
            }
            return defValue;
        }

        #endregion

        #region CommandLineArgs
        /// <summary>
        /// Parse CommandLineArgs
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, string> ParseArgs(string[] args)
        {
            if (args == null || args.Length == 0)
                args = Environment.GetCommandLineArgs();
            var argsWithoutLocation = args.ToArray();
            var extraArgs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            if (argsWithoutLocation.Length > 0)
            {
                for (var i = 0; i < argsWithoutLocation.Length; i++)
                {
                    var argument = argsWithoutLocation[i];
                    //Agent.LogInfo($" ParseArgs argument[{i}]={argument}");
                    if (string.IsNullOrWhiteSpace(argument)) continue;
                    argument = argument.Trim();

                    var key = "";
                    var val = "";
                    if (argument.StartsWith("----"))
                    {
                        key = argument.Substring(4);
                        val = argsWithoutLocation[++i];
                    }
                    else if (argument.StartsWith("---"))
                    {
                        key = argument.Substring(3);
                        val = argsWithoutLocation[++i];
                    }
                    else if (argument.StartsWith("--"))
                    {
                        key = argument.Substring(2);
                        val = argsWithoutLocation[++i];
                    }
                    else if (argument.StartsWith("-"))
                    {
                        key = argument.Substring(1);
                        val = argsWithoutLocation[++i];
                    }
                    else if (argument.Contains("="))
                    {
                        var arguments = argument.Split('=');
                        key = arguments[0];
                        val = arguments[1];
                    }
                    else if (argument.Contains(":"))
                    {
                        var arguments = argument.Split(':');
                        key = arguments[0];
                        val = arguments[1];
                    }
                    if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(val)) continue;

                    key = key.Trim();
                    val = val.Trim();

                    extraArgs[key] = val;
                }
            }
            return extraArgs;
        }
        /// <summary>
        ///  获取与指定键关联的值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="key"></param>
        /// <param name="defVal"></param>
        /// <returns></returns>
        public static string TryGetValue_(this IDictionary<string, string> obj, string key, string defVal = "")
        {
            if (obj == null || key.IsNullOrEmpty_())
                return defVal;

            var val = "";
            if (obj.TryGetValue(key, out val))
            {
                return val;
            }
            return defVal;
        }
        #endregion

        #region GenerateMD5
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public static string GenerateMD5(string txt)
        {
            using (var mi = System.Security.Cryptography.MD5.Create())
            {
                byte[] buffer = Encoding.Default.GetBytes(txt);
                //开始加密
                byte[] newBuffer = mi.ComputeHash(buffer);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < newBuffer.Length; i++)
                {
                    sb.Append(newBuffer[i].ToString("x2"));
                }
                return sb.ToString().ToLower();
            }
        }
        #endregion

        #region MapTo
        /// <summary>
        /// 映射，无需初始化（方便，但效率低）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T1">The type of the 1.</typeparam>
        /// <param name="t">The t.</param>
        /// <returns></returns>
        public static T1 MapTo<T, T1>(this T source)
        {
            var result = FastReflection.FastInstance<T1>(typeof(T1)); //(T1)Activator.CreateInstance(typeof(T1));
            return MapTo(source, result);
        }
        public static T1 MapTo<T, T1>(this T source, T1 result)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (source.GetType().Name == "List`1" || result.GetType().Name == "List`1")
            {
                //throw new Exception("形参有误！，请使用对象。");
                throw new Exception("列表映射请使用 MapList 方法");
            }
            if (result == null)
            {
                result = FastReflection.FastInstance<T1>(typeof(T1));
            }
            var tpropertyInfos = source.GetType().GetProperties();
            var t1propertyInfos = result.GetType().GetProperties();
            foreach (var tinfo in tpropertyInfos)
            {
                foreach (var t1info in t1propertyInfos)
                {
                    if (t1info.PropertyType.IsValueType || t1info.PropertyType.Name.StartsWith("String"))
                    {
                        if (tinfo.Name == t1info.Name)
                        {
                            try
                            {
                                object value = tinfo.GetValue(source, null);
                                var property = result.GetType().GetProperty(tinfo.Name);
                                if (property != null && property.CanWrite && value != null && !(value is DBNull))
                                {
                                    property.SetValue(result, value.ChangeType(property.PropertyType), null);
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                }

            }
            return result;
        }

        /// <summary>
        /// 映射，无需初始化（方便，但效率低）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T1">The type of the 1.</typeparam>
        /// <param name="t">The t.</param>
        /// <returns></returns>
        public static List<T1> MapList<T, T1>(this List<T> t)
        {
            List<T1> result = new List<T1>();
            if (t == null)
            {
                throw new Exception("未将对象引用设置到对象的实例。");
            }
            foreach (var item in t)
            {
                result.Add(MapTo<T, T1>(item));
            }
            return result;
        }
        #endregion

        #region JsonToObject
        /// <summary>
        ///JSON转对象
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T JsonToObject<T>(this string value)
        {
            if (value.IsJson())
                return JsonHelper.DeserializeObjectByJson<T>(value);
            else return default(T);
        }
        #endregion
        #region GetExceptionMessage
        public static string GetExceptionMessage(this Exception exception)
        {
            if (exception == null)
                return string.Empty;

            var message = exception.Message;
            if (exception.InnerException != null)
            {
                message += "|InnerException:" + GetExceptionMessage(exception.InnerException);
            }
            return message;
        }
        #endregion

        #region Replace
        /// <summary>
        /// 只替换第一个匹配项，写一个方法来实现这个功能。
        /// </summary>
        /// <param name="source"></param>
        /// <param name="match"></param>
        /// <param name="replacement"></param>
        /// <returns></returns>
        public static string Replace(string source, string match, string replacement)
        {
            char[] sArr = source.ToCharArray();
            char[] mArr = match.ToCharArray();
            char[] rArr = replacement.ToCharArray();
            int idx = IndexOf(sArr, mArr);
            if (idx == -1)
            {
                return source;
            }
            else
            {
                return new string(sArr.Take(idx).Concat(rArr).Concat(sArr.Skip(idx + mArr.Length)).ToArray());
            }
        }
        /// <summary>
        /// 查找字符数组在另一个字符数组中匹配的位置
        /// </summary>
        /// <param name="source">源字符数组</param>
        /// <param name="match">匹配字符数组</param>
        /// <returns>匹配的位置，未找到匹配则返回-1</returns>
        private static int IndexOf(char[] source, char[] match)
        {
            int idx = -1;
            for (int i = 0; i <= source.Length - match.Length; i++)
            {
                if (source[i] == match[0])
                {
                    bool isMatch = true;
                    for (int j = 0; j < match.Length; j++)
                    {
                        if (source[i + j] != match[j])
                        {
                            isMatch = false;
                            break;
                        }
                    }
                    if (isMatch)
                    {
                        idx = i;
                        break;
                    }
                }
            }
            return idx;
        }

        public static string RemovePostFix(this string str, params string[] postFixes)
        {
            if (str == null)
            {
                return null;
            }

            if (str == string.Empty)
            {
                return string.Empty;
            }

            if (postFixes.IsNullOrEmpty())
            {
                return str;
            }

            foreach (var postFix in postFixes)
            {
                if (str.EndsWith(postFix))
                {
                    return str.Left(str.Length - postFix.Length);
                }
            }

            return str;
        }

        public static string RemovePreFix(this string str, params string[] preFixes)
        {
            if (str == null)
            {
                return null;
            }

            if (str == string.Empty)
            {
                return string.Empty;
            }

            if (preFixes.IsNullOrEmpty())
            {
                return str;
            }

            foreach (var preFix in preFixes)
            {
                if (str.StartsWith(preFix))
                {
                    return str.Right(str.Length - preFix.Length);
                }
            }

            return str;
        }
        public static string Left(this string str, int len)
        {
            if (str == null)
            {
                throw new ArgumentNullException("str");
            }

            if (str.Length < len)
            {
                throw new ArgumentException("len argument can not be bigger than given string's length!");
            }

            return str.Substring(0, len);
        }


        public static string Right(this string str, int len)
        {
            if (str == null)
            {
                throw new ArgumentNullException("str");
            }

            if (str.Length < len)
            {
                throw new ArgumentException("len argument can not be bigger than given string's length!");
            }

            return str.Substring(str.Length - len, len);
        }
        public static string GetCamelCaseFirstWord(this string str)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }

            if (str.Length == 1)
            {
                return str;
            }

            var res = Regex.Split(str, @"(?=\p{Lu}\p{Ll})|(?<=\p{Ll})(?=\p{Lu})");

            if (res.Length < 1)
            {
                return str;
            }
            else
            {
                return res[0];
            }
        }

        public static string GetPascalCaseFirstWord(this string str)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }

            if (str.Length == 1)
            {
                return str;
            }

            var res = Regex.Split(str, @"(?=\p{Lu}\p{Ll})|(?<=\p{Ll})(?=\p{Lu})");

            if (res.Length < 2)
            {
                return str;
            }
            else
            {
                return res[1];
            }
        }

        public static string GetPascalOrCamelCaseFirstWord(this string str)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }

            if (str.Length == 1)
            {
                return str;
            }

            if (str[0] >= 65 && str[0] <= 90)
            {
                return GetPascalCaseFirstWord(str);
            }
            else
            {
                return GetCamelCaseFirstWord(str);
            }
        }

        #endregion
        #region 获取类中的属性
        /// <summary>
        /// 获取类中的属性
        /// </summary>
        /// <returns>所有属性名称</returns>
        public static List<string> GetPropertyNames<T>(this T t)
        {
            List<string> ListStr = new List<string>();
            if (t == null)
            {
                return ListStr;
            }
            System.Reflection.PropertyInfo[] properties = t.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            if (properties.Length <= 0)
            {
                return ListStr;
            }
            foreach (System.Reflection.PropertyInfo item in properties)
            {
                string name = item.Name; //名称
                object value = item.GetValue(t, null);  //值
                if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
                {
                    ListStr.Add(name);
                }
                else
                {
                    GetPropertyNames(value);
                }
            }
            return ListStr;
        }
        /// <summary>
        ///  获取类中的字段
        /// </summary>
        /// <returns>所有字段名称</returns>
        public static List<string> GetFieldNames<T>(this T t)
        {
            List<string> ListStr = new List<string>();
            if (t == null)
            {
                return ListStr;
            }
            System.Reflection.FieldInfo[] fields = t.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            if (fields.Length <= 0)
            {
                return ListStr;
            }
            foreach (System.Reflection.FieldInfo item in fields)
            {
                string name = item.Name; //名称
                object value = item.GetValue(t);  //值

                if (item.FieldType.IsValueType || item.FieldType.Name.StartsWith("String"))
                {
                    ListStr.Add(name);
                }
                else
                {
                    GetFieldNames(value);
                }
            }
            return ListStr;
        }
        #endregion
        #region 获得字符串中开始和结束字符串中间得值
        /// <summary>
        /// 获得字符串中开始和结束字符串中间得值
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="s">开始</param>
        /// <param name="e">结束</param>
        /// <returns></returns> 
        public static List<string> GetRegexValue(this string str, string s, string e)
        {
            s = s.Replace("(", "\\(").Replace(")", "\\)").Replace("[", "\\[").Replace("]", "\\]");
            e = e.Replace("(", "\\(").Replace(")", "\\)").Replace("[", "\\[").Replace("]", "\\]");

            var rg = new System.Text.RegularExpressions.Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))"
                , System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.Singleline);

            var lst = new List<string>();
            var mc = rg.Matches(str);
            foreach (System.Text.RegularExpressions.Match item in mc)
            {
                if (item.Value.IsNotNullOrEmpty())
                {
                    lst.Add(item.Value);
                }
            }
            return lst;
        }
        #endregion

        #region 启动一个独立进程
        /// <summary>
        /// 启动一个独立进程
        /// </summary>
        /// <param name="ServiceFullName"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        public static bool RunExeBlack(string ServiceFullName, string command)
        {
            var p = new System.Diagnostics.Process(); //实例一个Process类，启动一个独立进程
            try
            {
                p.StartInfo.FileName = ServiceFullName;  //设定程序名
                p.StartInfo.Arguments = command;  //设定程式执行参数   
                p.StartInfo.UseShellExecute = false;    //关闭Shell的使用
                p.StartInfo.RedirectStandardInput = false;  //重定向标准输入
                p.StartInfo.RedirectStandardOutput = false; //重定向标准输出  
                p.StartInfo.RedirectStandardError = false;   //重定向错误输出
                //p.StartInfo.Verb = "runas";         // 设置启动动作,确保以管理员身份运行
                //p.StartInfo.CreateNoWindow = true;  //设置不显示窗口
                p.Start();    //启动

                return true;
            }
            catch (Exception ex) { Log.Log.Error(ex.ToString()); return false; }
            finally { try { p.Close(); } catch { } }
        }
        /// <summary>
        /// 启动一个独立进程
        /// </summary>
        /// <param name="ServiceFullName"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        public static string RunExe(string ServiceFullName, string command)
        {
            var p = new System.Diagnostics.Process(); //实例一个Process类，启动一个独立进程
            try
            {
                p.StartInfo.FileName = ServiceFullName;  //设定程序名
                p.StartInfo.Arguments = command;  //设定程式执行参数   
                p.StartInfo.UseShellExecute = false;    //关闭Shell的使用
                p.StartInfo.RedirectStandardInput = true;  //重定向标准输入
                p.StartInfo.RedirectStandardOutput = true; //重定向标准输出  
                p.StartInfo.RedirectStandardError = true;   //重定向错误输出         
                p.StartInfo.CreateNoWindow = true;  //设置不显示窗口
                p.Start();    //启动

                return p.StandardOutput.ReadToEnd(); //从输出流取得命令执行结果
            }
            catch (Exception ex) { Log.Log.Error(ex.ToString()); return ex.ToString(); }
            finally { try { p.Close(); } catch { } }
        }
        /// <summary> 
        /// 执行CMD语句 
        /// </summary> 
        /// <param name="cmd">要执行的CMD命令</param> 
        public static void RunCmd(string cmd)
        {
            try
            {
                var proc = new System.Diagnostics.Process();
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.FileName = "cmd.exe";
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.RedirectStandardInput = true;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.Start();
                proc.StandardInput.WriteLine(cmd);
                proc.Close();
            }
            catch (Exception ex)
            {
                Log.Log.Error(ex.ToString());
            }
        }
        #endregion
    }
    /// <summary>
    /// 开始结束日期类型
    /// </summary>
    public enum StartAndEndDateType
    {
        /// <summary>
        /// 周
        /// </summary>
        [Description("周")]
        Week,
        /// <summary>
        /// 月
        /// </summary>
        [Description("月")]
        Month,
        /// <summary>
        /// 季度
        /// </summary>
        [Description("季度")]
        Season,
        /// <summary>
        /// 年
        /// </summary>
        [Description("年")]
        Year
    }
    #region enum TextCaseType
    /// <summary>转换大小写类型</summary>
    public enum TextCaseType
    {
        /// <summary>不处理</summary>
        None,
        /// <summary>小写</summary>
        LowerCase,
        /// <summary>大写</summary>
        UpperCase,
        /// <summary>首字母大写（每个单词的首字母大写）</summary>
        PascalCase,
        /// <summary>驼峰格式（首个单词的首字母小写，其余单词的首字母大写）</summary>
        CamelCase,
        /// <summary>以连字符分隔</summary>
        Hyphenate
    }
    #endregion

    public static class TypeHelper
    {
        public static bool IsFunc(this object obj)
        {
            if (obj == null)
            {
                return false;
            }

            var type = obj.GetType();
            if (!type.GetTypeInfo().IsGenericType)
            {
                return false;
            }

            return type.GetGenericTypeDefinition() == typeof(Func<>);
        }

        public static bool IsFunc<TReturn>(this object obj)
        {
            return obj != null && obj.GetType() == typeof(Func<TReturn>);
        }

        public static bool IsPrimitiveExtendedIncludingNullable(this Type type, bool includeEnums = false)
        {
            if (IsPrimitiveExtended(type, includeEnums))
            {
                return true;
            }

            if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                return IsPrimitiveExtended(type.GetGenericArguments()[0], includeEnums);
            }

            return false;
        }

        private static bool IsPrimitiveExtended(Type type, bool includeEnums)
        {
            if (type.GetTypeInfo().IsPrimitive)
            {
                return true;
            }

            if (includeEnums && type.GetTypeInfo().IsEnum)
            {
                return true;
            }

            return type == typeof(string) ||
                   type == typeof(decimal) ||
                   type == typeof(DateTime) ||
                   type == typeof(DateTimeOffset) ||
                   type == typeof(TimeSpan) ||
                   type == typeof(Guid);
        }
    }
}

